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
00085 #ifdef USE_PCH
00086 #include "lno_pch.h"
00087 #endif // USE_PCH
00088 #pragma hdrstop
00089
00090 const static char *source_file = __FILE__;
00091 const static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/be/lno/SCCS/s.lego_io.cxx $ $Revision: 1.5 $";
00092
00093 #include <sys/types.h>
00094 #include <alloca.h>
00095 #include <ctype.h>
00096 #include <limits.h>
00097
00098 #include "pu_info.h"
00099 #include "lnopt_main.h"
00100 #include "config_targ.h"
00101 #include "erbe.h"
00102 #include "stab.h"
00103 #include "strtab.h"
00104 #include "stblock.h"
00105 #include "lwn_util.h"
00106 #include "dep.h"
00107 #include "lnoutils.h"
00108 #include "lego_util.h"
00109 #include "lego_pragma.h"
00110 #include "scalar_expand.h"
00111 #include "wio.h"
00112 #include "lego_affinity.h"
00113 #include "prompf.h"
00114 #include "anl_driver.h"
00115 #include "debug.h"
00116
00117 #pragma weak New_Construct_Id
00118
00119 enum REF_TYPE {SINGLE_ELEMENT_REF,IMPLIED_DO_REF,TOTAL_REF,OTHER_REF};
00120
00121 class REFERENCE
00122 {
00123 public:
00124 REF_TYPE Ref_Type;
00125 mBOOL Array_Loaded;
00126 WN *Ref;
00127 REFERENCE(WN *ref, REF_TYPE ref_type, BOOL array_loaded) {
00128 Ref=ref; Ref_Type = ref_type; Array_Loaded = array_loaded; }
00129 };
00130
00131 typedef STACK<WN *> STACK_OF_WN;
00132 typedef STACK<REFERENCE> STACK_OF_REFERENCES;
00133
00134 static ST* Create_Tmp_Array(ST *st, WN *IO_node, WN **tmp_array_def,
00135 mBOOL *const_dimensions=FALSE);
00136 static void Copy_Array(WN *orig_array, ST* local_st, WN *IO_node,
00137 BOOL copy_in, WN *tmp_array_def);
00138 static void Copy_Array_Section(WN *orig_array, ST* local_st, WN *IO_node,
00139 BOOL copy_in, WN *tmp_array_def, mBOOL *const_dimensions);
00140 static void Get_IOS_Reshaped_Array_Refs(WN *io_stmt, STACK_OF_WN *namelists,
00141 STACK_OF_REFERENCES *refs);
00142 static void Lego_Fix_IO_Rec(WN *wn, STACK_OF_WN *namelists,
00143 BOOL *has_do_loops);
00144 static BOOL Constant_Dimension(WN *wn, mBOOL *well_behaved, BOOL nrs_var_read);
00145 static void Set_Constant_Dimensions(WN *ref, mBOOL *const_dimensions,
00146 INT num_dims, mBOOL *well_behaved);
00147
00148 extern void Fix_Up_Loop_Info(WN *IO_node, WN **loops, INT num_dims);
00149
00150
00151 void Lego_Fix_IO(WN *func_nd, BOOL *has_do_loops)
00152 {
00153 STACK_OF_WN namelists(Malloc_Mem_Pool);
00154 Lego_Fix_IO_Rec(func_nd,&namelists,has_do_loops);
00155 }
00156
00157 static inline BOOL ST_is_reshaped_var(ST *st)
00158 {
00159 return ST_class(st) == CLASS_VAR && ST_is_reshaped(st);
00160 }
00161
00162
00163 static BOOL Contains_Reshaped_Array(WN *wn)
00164 {
00165 OPCODE opcode = WN_opcode(wn);
00166 if (opcode == OPC_BLOCK) {
00167 WN *kid = WN_first (wn);
00168 while (kid) {
00169 if (Contains_Reshaped_Array(kid)) return TRUE;
00170 kid = WN_next(kid);
00171 }
00172 } else {
00173 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00174 if (Contains_Reshaped_Array(WN_kid(wn,kidno))) return TRUE;
00175 }
00176 }
00177 OPERATOR oper = OPCODE_operator(opcode);
00178 if ((oper == OPR_LDID) || (oper == OPR_LDA)) {
00179 if (ST_is_reshaped_var(WN_st(wn))) {
00180 return TRUE;
00181 }
00182 }
00183 return FALSE;
00184 }
00185
00186
00187 static BOOL Is_Valtmp(WN *wn)
00188 {
00189 if (WN_operator(wn) == OPR_INTRINSIC_OP) {
00190 switch (WN_intrinsic(wn)) {
00191
00192 case INTRN_I4VALTMP:
00193 case INTRN_I8VALTMP:
00194 case INTRN_U4VALTMP:
00195 case INTRN_U8VALTMP:
00196 case INTRN_F4VALTMP:
00197 case INTRN_F8VALTMP:
00198 case INTRN_FQVALTMP:
00199 case INTRN_C4VALTMP:
00200 case INTRN_C8VALTMP:
00201 case INTRN_CQVALTMP: return TRUE;
00202 }
00203 }
00204 return FALSE;
00205 }
00206
00207
00208
00209
00210
00211
00212 static BOOL Contains_Calls(WN *wn)
00213 {
00214 OPCODE opcode = WN_opcode(wn);
00215 if (opcode == OPC_BLOCK) {
00216 WN *kid = WN_first (wn);
00217 while (kid) {
00218 if (Contains_Calls(kid)) return TRUE;
00219 kid = WN_next(kid);
00220 }
00221 } else if (OPCODE_is_call(opcode)) {
00222 return TRUE;
00223 } else if (OPCODE_operator(opcode) == OPR_INTRINSIC_OP
00224 #ifdef KEY
00225 || OPCODE_operator(opcode) == OPR_PURE_CALL_OP
00226 #endif
00227 ) {
00228 if (Contains_Reshaped_Array(wn)) {
00229 return TRUE;
00230 }
00231 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00232 if (Contains_Calls(WN_kid(wn,kidno))) return TRUE;
00233 }
00234 } else {
00235 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00236 if (Contains_Calls(WN_kid(wn,kidno))) return TRUE;
00237 }
00238 }
00239 return FALSE;
00240 }
00241
00242
00243
00244
00245
00246 static void Substitute_Array(WN *orig_base, WN *tmp_array_def,
00247 INT num_dims, mBOOL *const_dimensions)
00248 {
00249 WN *orig_array = LWN_Get_Parent(orig_base);
00250 INT kidno=0;
00251 while (WN_kid(orig_array,kidno) != orig_base) kidno++;
00252
00253 WN *io = orig_base;
00254 while (WN_opcode(io) != OPC_IO) io = LWN_Get_Parent(io);
00255
00256
00257
00258
00259 WN *ldid = LWN_CreateLdid(
00260 OPCODE_make_op(OPR_LDID,Pointer_type,Pointer_type),
00261 tmp_array_def);
00262
00263 Du_Mgr->Add_Def_Use(tmp_array_def,io);
00264 LWN_Delete_Tree(WN_kid(orig_array,kidno));
00265 WN_kid(orig_array,kidno) = ldid;
00266 LWN_Set_Parent(ldid,orig_array);
00267
00268
00269 if (const_dimensions) {
00270 INT num_used_dimensions=0;
00271 INT i;
00272 for (i=0; i<num_dims; i++) {
00273 if (!const_dimensions[i]) num_used_dimensions++;
00274 }
00275 Is_True(num_used_dimensions,("Completely constant ref in Substitute_Array"));
00276 WN *parent = LWN_Get_Parent(orig_array);
00277 INT kidno=0;
00278 while (WN_kid(parent,kidno) != orig_array) kidno++;
00279
00280 WN *new_array = WN_Create(WN_opcode(orig_array),1+2*num_used_dimensions);
00281 WN_element_size(new_array) = WN_element_size(orig_array);
00282 WN_array_base(new_array) = LWN_Copy_Tree(WN_array_base(orig_array));
00283 INT j=0;
00284 for (i=0; i<num_used_dimensions; i++) {
00285 while (const_dimensions[j]) j++;
00286 WN_array_dim(new_array,i) = LWN_Copy_Tree(WN_array_dim(orig_array,j));
00287 WN_array_index(new_array,i) = LWN_Copy_Tree(WN_array_index(orig_array,j));
00288 j++;
00289 }
00290 for (i=0; i<WN_kid_count(new_array); i++) {
00291 LWN_Set_Parent(WN_kid(new_array,i),new_array);
00292 }
00293 LWN_Delete_Tree(orig_array);
00294 WN_kid(parent,kidno) = new_array;
00295 LWN_Set_Parent(new_array,parent);
00296 }
00297 }
00298
00299 static void Lego_Fix_IO_Rec(WN *wn, STACK_OF_WN *namelists, BOOL *has_do_loops)
00300 {
00301 OPCODE opcode = WN_opcode(wn);
00302 if (opcode == OPC_BLOCK) {
00303 WN *kid = WN_first (wn);
00304 while (kid) {
00305 Lego_Fix_IO_Rec(kid,namelists,has_do_loops);
00306 kid = WN_next(kid);
00307 }
00308 } else if (opcode == OPC_IO) {
00309 MEM_POOL_Push(&LNO_local_pool);
00310 STACK_OF_REFERENCES *refs =
00311 CXX_NEW(STACK_OF_REFERENCES(&LNO_local_pool),&LNO_local_pool);
00312
00313 Get_IOS_Reshaped_Array_Refs(wn,namelists,refs);
00314
00315 if (refs->Elements()) {
00316 if (Contains_Calls(wn)) {
00317 ErrMsgSrcpos(EC_LNO_Generic_Error, WN_Get_Linenum(wn),
00318 "We currently do not support IO statements containing calls and reshaped arrays\n");
00319 }
00320 }
00321
00322 ST **array_sts = CXX_NEW_ARRAY(ST *, refs->Elements(), &LNO_local_pool);
00323 INT i;
00324 for (i=0; i<refs->Elements(); i++) {
00325 array_sts[i] = WN_st(refs->Bottom_nth(i).Ref);
00326 }
00327 for (i=0; i<refs->Elements(); i++) {
00328 ST *st = array_sts[i];
00329 BOOL array_loaded = refs->Bottom_nth(i).Array_Loaded;
00330 BOOL non_single_element_refs =
00331 (refs->Bottom_nth(i).Ref_Type != SINGLE_ELEMENT_REF);
00332 BOOL non_array_ref =
00333 (refs->Bottom_nth(i).Ref_Type == OTHER_REF);
00334 BOOL total_ref = (refs->Bottom_nth(i).Ref_Type == TOTAL_REF);
00335 BOOL array_stored = !array_loaded;
00336
00337 BOOL done_before = FALSE;
00338 for (INT j=0; j<i && !done_before; j++) {
00339 ST *j_st = array_sts[j];
00340 if (j_st == st) {
00341 done_before = TRUE;
00342 }
00343 }
00344 if (!done_before) {
00345 INT multiple_refs = FALSE;
00346 INT j;
00347 for (j=i+1; j<refs->Elements(); j++) {
00348 if (array_sts[j] == st) {
00349 multiple_refs = TRUE;
00350 if (refs->Bottom_nth(j).Ref_Type != SINGLE_ELEMENT_REF) {
00351 non_single_element_refs = TRUE;
00352 }
00353 if (refs->Bottom_nth(j).Ref_Type == OTHER_REF) {
00354 non_array_ref = TRUE;
00355 } else if (refs->Bottom_nth(j).Ref_Type == TOTAL_REF) {
00356 total_ref = TRUE;
00357 }
00358 array_loaded |= refs->Bottom_nth(j).Array_Loaded;
00359 array_stored |= !(refs->Bottom_nth(j).Array_Loaded);
00360 }
00361 }
00362
00363 DISTR_ARRAY* dact = Lookup_DACT (array_sts[i]);
00364 INT num_dims = dact->Dinfo()->Num_Dim();
00365 if (non_single_element_refs) {
00366 if (!multiple_refs && (refs->Bottom_nth(i).Ref_Type == IMPLIED_DO_REF)) {
00367 MEM_POOL_Push(&LNO_local_pool);
00368 mBOOL *const_dimensions=
00369 const_dimensions=CXX_NEW_ARRAY(mBOOL,num_dims,&LNO_local_pool);
00370 mBOOL well_behaved = TRUE;
00371 Set_Constant_Dimensions(refs->Bottom_nth(i).Ref, const_dimensions,
00372 num_dims, &well_behaved);
00373 BOOL contains_non_const = FALSE;
00374 for (INT count=0; count<num_dims && !contains_non_const; count++) {
00375 if (!const_dimensions[count]) contains_non_const = TRUE;
00376 }
00377 if (well_behaved && contains_non_const) {
00378 WN *orig_array = LWN_Get_Parent(refs->Bottom_nth(i).Ref);
00379 WN *tmp_array_def;
00380 ST* tmp_array =
00381 Create_Tmp_Array(st,wn,&tmp_array_def, const_dimensions);
00382 if (array_loaded) {
00383 Copy_Array_Section(orig_array, tmp_array,wn,TRUE,tmp_array_def,
00384 const_dimensions);
00385 *has_do_loops = TRUE;
00386 }
00387 if (array_stored) {
00388 Copy_Array_Section(orig_array, tmp_array,wn,FALSE,tmp_array_def,
00389 const_dimensions);
00390 *has_do_loops = TRUE;
00391 }
00392 Substitute_Array(refs->Bottom_nth(i).Ref,tmp_array_def,
00393 num_dims,const_dimensions);
00394 }
00395 CXX_DELETE_ARRAY(const_dimensions,&LNO_local_pool);
00396 MEM_POOL_Pop(&LNO_local_pool);
00397 } else if (total_ref || non_array_ref || multiple_refs) {
00398 WN *orig_array = LWN_Get_Parent(refs->Bottom_nth(i).Ref);
00399 WN *tmp_array_def;
00400 ST* tmp_array = Create_Tmp_Array(st,wn,&tmp_array_def);
00401
00402 if (array_loaded || !total_ref) {
00403 Copy_Array(orig_array,tmp_array,wn,TRUE,tmp_array_def);
00404 *has_do_loops = TRUE;
00405 }
00406 if (array_stored) {
00407 Copy_Array(orig_array,tmp_array,wn,FALSE, tmp_array_def);
00408 *has_do_loops = TRUE;
00409 }
00410
00411 Substitute_Array(refs->Bottom_nth(i).Ref,tmp_array_def,
00412 num_dims,0);
00413 for (j=i+1; multiple_refs && j<refs->Elements(); j++) {
00414 ST *j_st = array_sts[j];
00415 if (j_st == st) {
00416 Substitute_Array(refs->Bottom_nth(j).Ref,tmp_array_def,
00417 num_dims,0);
00418 }
00419 }
00420 }
00421 }
00422 }
00423 }
00424
00425 CXX_DELETE_ARRAY(array_sts,&LNO_local_pool);
00426 CXX_DELETE(refs,&LNO_local_pool);
00427 MEM_POOL_Pop(&LNO_local_pool);
00428 } else {
00429 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00430 Lego_Fix_IO_Rec(WN_kid(wn,kidno),namelists,has_do_loops);
00431 }
00432 }
00433 }
00434
00435 inline BOOL
00436 Is_IO_List_Item(WN *item)
00437 {
00438 return (WN_io_item(item) >= IOL_ARRAY && WN_io_item(item) <= IOL_VAR);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 BOOL Nrs_Var_Read(WN *io)
00451 {
00452 if ((WN_io_statement(io) == IOS_READ) ||
00453 (WN_io_statement(io) == IOS_CR_FRF) ||
00454 (WN_io_statement(io) == IOS_CR_FRU) ||
00455 (WN_io_statement(io) == IOS_ACCEPT) ||
00456 (WN_io_statement(io) == IOS_DECODE)) {
00457 INT count = 0;
00458 for (INT i = 0; i < WN_kid_count(io); i++) {
00459 WN *item = WN_kid(io, i);
00460 if (Is_IO_List_Item(item)) {
00461 count++;
00462 if (count > 1) return TRUE;
00463 }
00464 }
00465 return FALSE;
00466 } else {
00467 return FALSE;
00468 }
00469 }
00470
00471
00472 static BOOL Loop_Bound_Constant(WN *wn, BOOL nrs_var_read)
00473 {
00474 OPCODE opcode = WN_opcode(wn);
00475 OPERATOR oper = OPCODE_operator(opcode);
00476 if (OPCODE_is_load(opcode)) {
00477 if (nrs_var_read) return FALSE;
00478 if ((oper == OPR_LDID) || (oper == OPR_LDA)) {
00479 if (ST_is_reshaped_var(WN_st(wn))) {
00480 return FALSE;
00481 }
00482 }
00483 } else if (oper == OPR_INTRINSIC_OP) {
00484 if (Is_Valtmp(wn)) {
00485 return
00486 Loop_Bound_Constant(WN_kid0(wn),nrs_var_read);
00487 }
00488 return FALSE;
00489 }
00490 #ifdef KEY
00491 else if (oper == OPR_PURE_CALL_OP)
00492 return FALSE;
00493 #endif
00494 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00495 if (!Loop_Bound_Constant(WN_kid(wn,kidno),nrs_var_read)) {
00496 return FALSE;
00497 }
00498 }
00499 return TRUE;
00500 }
00501
00502
00503
00504 static BOOL Loop_Bounds_Constant(WN *ref, BOOL nrs_var_read)
00505 {
00506 WN *do_loop=LWN_Get_Parent(ref);
00507 while (WN_opcode(do_loop) != OPC_IO) {
00508 do_loop = LWN_Get_Parent(do_loop);
00509 OPERATOR oper = WN_operator(do_loop);
00510 if ((oper == OPR_IO_ITEM) &&
00511 (WN_io_item(do_loop) == IOL_IMPLIED_DO)) {
00512 if (!Loop_Bound_Constant(WN_start(do_loop),nrs_var_read)) {
00513 return FALSE;
00514 }
00515 if (!Loop_Bound_Constant(WN_end(do_loop),nrs_var_read)) {
00516 return FALSE;
00517 }
00518 if (WN_operator(WN_step(do_loop)) != OPR_INTCONST) {
00519 return FALSE;
00520 }
00521 }
00522 }
00523 return TRUE;
00524 }
00525
00526
00527
00528
00529
00530
00531 static void Set_Constant_Dimensions(WN *ref, mBOOL *const_dimensions, INT num_dims,
00532 mBOOL *well_behaved)
00533 {
00534 WN *array = LWN_Get_Parent(ref);
00535 WN *parent = array;
00536 while (WN_opcode(parent) != OPC_IO) parent = LWN_Get_Parent(parent);
00537 BOOL nrs_var_read = Nrs_Var_Read(parent);
00538 if (!Loop_Bounds_Constant(array,nrs_var_read)) {
00539 *well_behaved = FALSE;
00540 return;
00541 }
00542 for (INT i=0; i<num_dims; i++) {
00543 const_dimensions[i] = Constant_Dimension(WN_array_index(array,i),
00544 well_behaved, nrs_var_read);
00545 }
00546 }
00547
00548
00549
00550 static BOOL Constant_Dimension(WN *wn, mBOOL *well_behaved, BOOL nrs_var_read)
00551 {
00552
00553 OPCODE opcode = WN_opcode(wn);
00554 OPERATOR oper = OPCODE_operator(opcode);
00555 if (OPCODE_is_load(opcode)) {
00556 if (nrs_var_read) {
00557 *well_behaved = FALSE;
00558 return FALSE;
00559 }
00560 if (oper != OPR_LDID) {
00561 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00562 if (!Constant_Dimension(WN_kid(wn,kidno),well_behaved,nrs_var_read)) {
00563 return FALSE;
00564 }
00565 }
00566 } else {
00567 ST *st = WN_st(wn);
00568 if (ST_class(st) == CLASS_PREG) return TRUE;
00569
00570 WN *do_loop = LWN_Get_Parent(wn);
00571 OPCODE opcode = WN_opcode(do_loop);
00572 while (opcode != OPC_IO) {
00573 OPERATOR oper = OPCODE_operator(opcode);
00574 if ((oper == OPR_IO_ITEM) &&
00575 (WN_io_item(do_loop) == IOL_IMPLIED_DO)) {
00576 WN *index = WN_index(do_loop);
00577 if ((WN_st(index) == st) &&
00578 (WN_offset(index) == WN_offset(wn))) {
00579 return FALSE;
00580 }
00581 }
00582 do_loop = LWN_Get_Parent(do_loop);
00583 opcode = WN_opcode(do_loop);
00584 }
00585 return TRUE;
00586 }
00587 } else if (oper == OPR_LDA) {
00588 if (ST_is_reshaped_var(WN_st(wn))) {
00589 *well_behaved = FALSE;
00590 return FALSE;
00591 }
00592 return TRUE;
00593 } else {
00594 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00595 if (!Constant_Dimension(WN_kid(wn,kidno),well_behaved,nrs_var_read)) {
00596 return FALSE;
00597 }
00598 }
00599 }
00600 return TRUE;
00601 }
00602
00603
00604
00605 static ST* Create_Tmp_Array(ST *array_st, WN *IO_node, WN **tmp_array_def,
00606 mBOOL *const_dimensions)
00607 {
00608 SYMBOL symb;
00609 static INT number;
00610 TY_IDX element_type;
00611 if (TY_kind(ST_type(array_st)) == KIND_POINTER) {
00612 element_type = TY_AR_etype(TY_pointed(ST_type(array_st)));
00613 } else {
00614 Is_True(TY_kind(ST_type(array_st)) == KIND_ARRAY,
00615 ("Non-array,non-pointer in Create_Tmp_Array"));
00616 element_type = TY_AR_etype(ST_type(array_st));
00617 }
00618 TYPE_ID machine_element_type = TY_mtype(element_type);
00619
00620
00621 DISTR_ARRAY* dact = Lookup_DACT (array_st);
00622 INT j=0;
00623 if (const_dimensions) {
00624 while (const_dimensions[j]) j++;
00625 }
00626 INT element_size;
00627 switch(machine_element_type) {
00628 case MTYPE_I1: case MTYPE_U1: element_size=1; break;
00629 case MTYPE_I2: case MTYPE_U2: element_size=2; break;
00630 case MTYPE_I4: case MTYPE_U4: case MTYPE_F4: element_size=4; break;
00631 case MTYPE_I8: case MTYPE_U8: case MTYPE_F8: case MTYPE_C4: element_size=8; break;
00632 #if defined(TARG_IA64)
00633 case MTYPE_F10: element_size=16; break;
00634 #endif
00635 case MTYPE_C8: case MTYPE_FQ: element_size=16; break;
00636 case MTYPE_CQ: element_size=32; break;
00637 }
00638
00639 WN *bsz = LWN_CreateExp2(OPCODE_make_op(OPR_MPY,Pointer_type,MTYPE_V),
00640 LWN_Make_Icon(Pointer_type,element_size),dact->Array_Size_WN(j));
00641 INT num_dims = dact->Dinfo()->Num_Dim();
00642 for (INT i=j+1; i<num_dims; i++) {
00643 if (!const_dimensions || !const_dimensions[i]) {
00644 bsz = LWN_CreateExp2(OPCODE_make_op(OPR_MPY,Pointer_type,MTYPE_V),
00645 bsz,dact->Array_Size_WN(i));
00646 }
00647 }
00648
00649 SE_Symbols_For_SE(&symb,"tmp_io",number,machine_element_type);
00650 *tmp_array_def =
00651 Get_Expansion_Space(symb,bsz,"tmp_io",number++,machine_element_type,
00652 IO_node,IO_node,IO_node);
00653 return symb.St();
00654 }
00655
00656
00657
00658
00659
00660
00661
00662 static void IO_Copy_Defs(WN *io, WN *expr, WN **loops, INT num_loops)
00663 {
00664 OPCODE opc = WN_opcode(expr);
00665 if (OPCODE_is_load(opc)) {
00666 OPERATOR oper = OPCODE_operator(opc);
00667 BOOL is_index = FALSE;
00668 WN *index;
00669 if (oper == OPR_LDID) {
00670 for (INT i=0; i<num_loops && !is_index; i++) {
00671 if (WN_st(expr) == WN_st(WN_start(loops[i]))) {
00672 if (WN_offset(expr) == WN_offset(WN_start(loops[i]))) {
00673 is_index = TRUE;
00674 index = loops[i];
00675 }
00676 }
00677 }
00678 } else {
00679 for (INT kidno=0; kidno<WN_kid_count(expr); kidno++) {
00680 IO_Copy_Defs(io,WN_kid(expr,kidno),loops,num_loops);
00681 }
00682 }
00683 if (is_index) {
00684 Du_Mgr->Add_Def_Use(WN_start(index),expr);
00685 Du_Mgr->Add_Def_Use(WN_step(index),expr);
00686 DEF_LIST* deflist = Du_Mgr->Ud_Get_Def(expr);
00687 deflist->Set_loop_stmt(index);
00688 } else {
00689 DEF_LIST* deflist = Du_Mgr->Ud_Get_Def(io);
00690 if (deflist) {
00691 DEF_LIST_ITER iter(deflist);
00692 for (DU_NODE* n = iter.First(); !iter.Is_Empty(); n = iter.Next()) {
00693 WN* def = n->Wn();
00694 if (def != io) {
00695 if (deflist->Incomplete()) {
00696 Du_Mgr->Add_Def_Use(def, expr);
00697 } else if ((oper == OPR_LDID) ||
00698 (WN_operator(def) == OPR_STID)) {
00699 if (!OPCODE_is_store(WN_opcode(def)) ||
00700 (Aliased(Alias_Mgr,expr,def) != NOT_ALIASED)) {
00701 Du_Mgr->Add_Def_Use(def, expr);
00702 }
00703 }
00704 }
00705 }
00706 DEF_LIST* deflist2 = Du_Mgr->Ud_Get_Def(expr);
00707 if (deflist2) deflist2->Set_loop_stmt(deflist->Loop_stmt());
00708 if (deflist->Incomplete()) deflist2->Set_Incomplete();
00709 }
00710 }
00711 } else {
00712 for (INT kidno=0; kidno<WN_kid_count(expr); kidno++) {
00713 IO_Copy_Defs(io,WN_kid(expr,kidno),loops,num_loops);
00714 }
00715 }
00716 }
00717
00718
00719
00720 static void Copy_Array(WN *orig_array, ST* local_st, WN *IO_node,
00721 BOOL copy_in, WN *tmp_array_def)
00722 {
00723 ST *array_st = WN_st(WN_array_base(orig_array));
00724 MEM_POOL_Push(&LNO_local_pool);
00725 DISTR_ARRAY* dact = Lookup_DACT (array_st);
00726 Is_True(dact && dact->Dinfo()->IsReshaped(),
00727 ("Copy_Array called on non-reshaped array "));
00728 INT num_dims = dact->Dinfo()->Num_Dim();
00729 WN *alias_host = NULL;
00730
00731
00732 WN *insert_before;
00733 WN *insert_parent = LWN_Get_Parent(IO_node);
00734 WN *do_loop;
00735 if (copy_in) {
00736 insert_before = IO_node;
00737 } else {
00738 insert_before = WN_next(IO_node);
00739 }
00740
00741 TYPE_ID index_type;
00742
00743
00744 if ((Pointer_type == MTYPE_A8) || (Pointer_type == MTYPE_U8) ||
00745 (Pointer_type == MTYPE_I8)) {
00746
00747 index_type = MTYPE_I8;
00748 } else {
00749 index_type = MTYPE_I4;
00750 }
00751
00752 char name[20];
00753 WN **loop_starts = CXX_NEW_ARRAY(WN *,num_dims,&LNO_local_pool);
00754 WN **loop_steps = CXX_NEW_ARRAY(WN *,num_dims,&LNO_local_pool);
00755 WN **loops = CXX_NEW_ARRAY(WN *,num_dims,&LNO_local_pool);
00756 INT i;
00757 for (i=0; i<num_dims; i++) {
00758 sprintf(name,"copy_%d",i);
00759 WN_OFFSET index_var_num;
00760 ST* index_var_st;
00761 #ifdef _NEW_SYMTAB
00762 index_var_num = Create_Preg(index_type,name);
00763 #else
00764 index_var_num = Create_Preg(index_type,name,NULL);
00765 #endif
00766 index_var_st = MTYPE_To_PREG(index_type);
00767 WN *index = WN_CreateIdname(index_var_num,index_var_st);
00768 WN *start = LWN_CreateStid(OPCODE_make_op(OPR_STID,MTYPE_V,index_type),
00769 index_var_num, index_var_st,Be_Type_Tbl(index_type),
00770 LWN_Make_Icon(index_type,0));
00771 Create_alias(Alias_Mgr,start);
00772 LWN_Copy_Linenumber(IO_node,start);
00773 loop_starts[i] = start;
00774 WN *end_use =
00775 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),start);
00776 WN *num_iters = dact->Array_Size_WN(i);
00777 WN *end = LWN_CreateExp2
00778 (OPCODE_make_op(OPR_LT,Boolean_type,index_type),end_use, num_iters);
00779 WN *step_use =
00780 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),start);
00781 WN *add = LWN_CreateExp2(OPCODE_make_op(OPR_ADD,index_type,MTYPE_V),
00782 step_use, LWN_Make_Icon(index_type,1));
00783 WN *step = LWN_CreateStid(WN_opcode(start),start,add);
00784 LWN_Copy_Linenumber(IO_node,step);
00785 loop_steps[i] = start;
00786 do_loop = LWN_CreateDO(index,start,end,step,WN_CreateBlock());
00787 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
00788 INT new_id = New_Construct_Id();
00789 WN_MAP32_Set(Prompf_Id_Map, do_loop, new_id);
00790 Prompf_Info->Dsm_Io(new_id, WN_Whirl_Linenum(IO_node),
00791 (char*) WB_Whirl_Symbol(do_loop));
00792 }
00793 loops[i] = do_loop;
00794 LWN_Copy_Linenumber(IO_node,do_loop);
00795 LWN_Copy_Linenumber(IO_node,WN_do_body(do_loop));
00796 LWN_Insert_Block_Before(insert_parent,insert_before,do_loop);
00797 insert_before = NULL;
00798 insert_parent = WN_do_body(do_loop);
00799
00800 Du_Mgr->Add_Def_Use(start,end_use);
00801 Du_Mgr->Add_Def_Use(step,end_use);
00802 Du_Mgr->Add_Def_Use(start,step_use);
00803 Du_Mgr->Add_Def_Use(step,step_use);
00804 DEF_LIST *deflist = Du_Mgr->Ud_Get_Def(end_use);
00805 deflist->Set_loop_stmt(do_loop);
00806 deflist = Du_Mgr->Ud_Get_Def(step_use);
00807 deflist->Set_loop_stmt(do_loop);
00808
00809 }
00810
00811
00812 TY_IDX element_type;
00813 if (TY_kind(ST_type(array_st)) == KIND_POINTER) {
00814 element_type = TY_AR_etype(TY_pointed(ST_type(array_st)));
00815 } else {
00816 Is_True(TY_kind(ST_type(array_st)) == KIND_ARRAY,
00817 ("Non-array,non-pointer in Copy_Array"));
00818 element_type = TY_AR_etype(ST_type(array_st));
00819 }
00820 TYPE_ID machine_element_type = TY_mtype(element_type);
00821
00822
00823 OPCODE op_array = OPCODE_make_op(OPR_ARRAY,Pointer_type,MTYPE_V);
00824
00825 WN *array_base=dact->Dinfo()->Load_Distr_Array();
00826
00827 WN *local_base =
00828 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,Pointer_type,Pointer_type),tmp_array_def);
00829 Du_Mgr->Add_Def_Use(tmp_array_def,local_base);
00830
00831
00832 WN *array_wn = WN_Create(op_array,1+2*num_dims);
00833 WN *local_wn = WN_Create(op_array,1+2*num_dims);
00834 WN_element_size(array_wn) = TY_size(element_type);
00835 WN_element_size(local_wn) = TY_size(element_type);
00836 WN_array_base(array_wn) = array_base;
00837 WN_array_base(local_wn) = local_base;
00838
00839 for (i=0; i<num_dims; i++) {
00840 WN_array_index(local_wn,i) =
00841 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),loop_starts[i]);
00842 Du_Mgr->Add_Def_Use(loop_starts[i],WN_array_index(local_wn,i));
00843 Du_Mgr->Add_Def_Use(loop_steps[i],WN_array_index(local_wn,i));
00844 DEF_LIST *deflist = Du_Mgr->Ud_Get_Def(WN_array_index(local_wn,i));
00845 deflist->Set_loop_stmt(loops[i]);
00846 WN_array_dim(local_wn,i) = dact->Array_Size_WN(i);
00847 }
00848
00849 for (i=0; i<num_dims; i++) {
00850 WN_array_index(array_wn,i) =
00851 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),loop_starts[i]);
00852 Du_Mgr->Add_Def_Use(loop_starts[i],WN_array_index(array_wn,i));
00853 Du_Mgr->Add_Def_Use(loop_steps[i],WN_array_index(array_wn,i));
00854 DEF_LIST *deflist = Du_Mgr->Ud_Get_Def(WN_array_index(array_wn,i));
00855 deflist->Set_loop_stmt(loops[i]);
00856 WN_array_dim(array_wn,i) = dact->Array_Size_WN(i);
00857 }
00858 for (i=0; i<WN_kid_count(array_wn); i++) {
00859 LWN_Set_Parent(WN_kid(array_wn,i),array_wn);
00860 }
00861 for (i=0; i<WN_kid_count(local_wn); i++) {
00862 LWN_Set_Parent(WN_kid(local_wn,i),local_wn);
00863 }
00864 WN *store;
00865 if (copy_in) {
00866 WN *value = LWN_CreateIload(
00867 OPCODE_make_op(OPR_ILOAD,machine_element_type,machine_element_type),
00868 0,element_type,Make_Pointer_Type(element_type),array_wn);
00869 if (ST_sclass(array_st) == SCLASS_FORMAL) {
00870 Create_formal_alias(Alias_Mgr,WN_st(array_base),array_base,value);
00871 } else if (WN_operator(array_base)==OPR_LDA) {
00872 Create_lda_array_alias(Alias_Mgr,array_base,value);
00873 } else {
00874 Create_unique_pointer_alias(Alias_Mgr,WN_st(array_base),array_base,value);
00875 }
00876
00877 store = LWN_CreateIstore(
00878 OPCODE_make_op(OPR_ISTORE,MTYPE_V,machine_element_type),
00879 0,Make_Pointer_Type(element_type),value,local_wn);
00880 if (alias_host==NULL) {
00881 Create_unique_pointer_alias(Alias_Mgr,local_st,NULL, store);
00882 alias_host = store;
00883 } else {
00884 Copy_alias_info(Alias_Mgr, alias_host, store);
00885 }
00886
00887 LWN_Copy_Linenumber(IO_node,store);
00888 } else {
00889 WN *value = LWN_CreateIload(
00890 OPCODE_make_op(OPR_ILOAD,machine_element_type,machine_element_type),
00891 0,element_type,Make_Pointer_Type(element_type),local_wn);
00892 if (alias_host==NULL) {
00893 Create_unique_pointer_alias(Alias_Mgr,local_st,NULL, value);
00894 alias_host = value;
00895 } else {
00896 Copy_alias_info(Alias_Mgr, alias_host, value);
00897 }
00898
00899 store = LWN_CreateIstore(
00900 OPCODE_make_op(OPR_ISTORE,MTYPE_V,machine_element_type),
00901 0,Make_Pointer_Type(element_type),value,array_wn);
00902 if (ST_sclass(array_st) == SCLASS_FORMAL) {
00903 Create_formal_alias(Alias_Mgr,WN_st(array_base),array_base,store);
00904 } else if (WN_operator(array_base)==OPR_LDA) {
00905 Create_lda_array_alias(Alias_Mgr,array_base,store);
00906 } else {
00907 Create_unique_pointer_alias(Alias_Mgr,WN_st(array_base),array_base,store);
00908 }
00909 LWN_Copy_Linenumber(IO_node,store);
00910 }
00911
00912 Fix_Up_Loop_Info(IO_node,loops,num_dims);
00913
00914 LWN_Insert_Block_Before(WN_do_body(do_loop),NULL,store);
00915 CXX_DELETE_ARRAY(loop_starts,&LNO_local_pool);
00916 CXX_DELETE_ARRAY(loop_steps,&LNO_local_pool);
00917 CXX_DELETE_ARRAY(loops,&LNO_local_pool);
00918 MEM_POOL_Pop(&LNO_local_pool);
00919 }
00920
00921
00922 static void Copy_Array_Section(WN *orig_array, ST* local_st, WN *IO_node,
00923 BOOL copy_in, WN *tmp_array_def, mBOOL *const_dimensions)
00924 {
00925 ST *array_st = WN_st(WN_array_base(orig_array));
00926 MEM_POOL_Push(&LNO_local_pool);
00927 DISTR_ARRAY* dact = Lookup_DACT (array_st);
00928 Is_True(dact && dact->Dinfo()->IsReshaped(),
00929 ("Copy_Array called on non-reshaped array "));
00930 INT array_dims = dact->Dinfo()->Num_Dim();
00931 INT local_dims = array_dims;
00932 INT i;
00933 for (i=0; i<array_dims; i++) {
00934 if (const_dimensions[i]) {
00935 local_dims--;
00936 }
00937 }
00938 WN *alias_host = NULL;
00939
00940
00941 STACK_OF_WN *implied_dos = CXX_NEW(STACK_OF_WN(&LNO_local_pool),&LNO_local_pool);
00942 WN *idos = LWN_Get_Parent(orig_array);
00943 while (WN_opcode(idos) != OPC_IO) {
00944 idos = LWN_Get_Parent(idos);
00945 OPERATOR oper = WN_operator(idos);
00946 if ((oper == OPR_IO_ITEM) &&
00947 (WN_io_item(idos) == IOL_IMPLIED_DO)) {
00948 implied_dos->Push(idos);
00949 }
00950 }
00951
00952 WN *insert_before;
00953 WN *insert_parent = LWN_Get_Parent(IO_node);
00954 WN *do_loop;
00955 if (copy_in) {
00956 insert_before = IO_node;
00957 } else {
00958 insert_before = WN_next(IO_node);
00959 }
00960
00961 WN **loop_starts = CXX_NEW_ARRAY(WN *,implied_dos->Elements(),&LNO_local_pool);
00962 WN **loop_steps = CXX_NEW_ARRAY(WN *,implied_dos->Elements(),&LNO_local_pool);
00963 WN **loops = CXX_NEW_ARRAY(WN *,implied_dos->Elements(),&LNO_local_pool);
00964 for (i=0; i<implied_dos->Elements(); i++) {
00965 WN *implied_do = implied_dos->Top_nth(i);
00966 TYPE_ID index_type = WN_rtype(WN_start(implied_do));
00967
00968 WN *index = WN_CreateIdname(WN_offset(WN_index(implied_do)),WN_st(WN_index(implied_do)));
00969 WN *start = LWN_CreateStid(OPCODE_make_op(OPR_STID,MTYPE_V,index_type),
00970 WN_offset(WN_index(implied_do)),
00971 WN_st(WN_index(implied_do)),
00972 Be_Type_Tbl(index_type),
00973 LWN_Copy_Tree(WN_start(implied_do)));
00974 Create_alias(Alias_Mgr,start);
00975 LWN_Copy_Linenumber(IO_node,start);
00976 loop_starts[i] = start;
00977 WN *end;
00978 WN *end_use = LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),
00979 start);
00980 WN *end_bound;
00981 if (Is_Valtmp(WN_end(implied_do))) {
00982 end_bound = LWN_Copy_Tree(WN_kid0(WN_end(implied_do)));
00983 } else {
00984 end_bound = LWN_Copy_Tree(WN_end(implied_do));
00985 }
00986
00987 if (WN_const_val(WN_step(implied_do)) > 0) {
00988 end = LWN_CreateExp2(OPCODE_make_op(OPR_LE,Boolean_type,index_type),
00989 end_use, end_bound);
00990 } else {
00991 end = LWN_CreateExp2(OPCODE_make_op(OPR_GE,Boolean_type,index_type),
00992 end_use, end_bound);
00993 }
00994 WN *step_use =
00995 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,index_type,index_type),start);
00996 WN *add = LWN_CreateExp2(OPCODE_make_op(OPR_ADD,index_type,MTYPE_V),
00997 step_use, LWN_Copy_Tree(WN_step(implied_do)));
00998 WN *step = LWN_CreateStid(WN_opcode(start),start,add);
00999
01000 LWN_Copy_Linenumber(IO_node,step);
01001 loop_steps[i] = start;
01002 do_loop = LWN_CreateDO(index,start,end,step,WN_CreateBlock());
01003 if (Prompf_Info != NULL && Prompf_Info->Is_Enabled()) {
01004 INT new_id = New_Construct_Id();
01005 WN_MAP32_Set(Prompf_Id_Map, do_loop, new_id);
01006 Prompf_Info->Dsm_Io(new_id, WN_Whirl_Linenum(IO_node),
01007 (char*) WB_Whirl_Symbol(do_loop));
01008 }
01009 loops[i] = do_loop;
01010 LWN_Copy_Linenumber(IO_node,do_loop);
01011 LWN_Copy_Linenumber(IO_node,WN_do_body(do_loop));
01012 LWN_Insert_Block_Before(insert_parent,insert_before,do_loop);
01013 insert_before = NULL;
01014 insert_parent = WN_do_body(do_loop);
01015
01016 Du_Mgr->Add_Def_Use(start,step_use);
01017 Du_Mgr->Add_Def_Use(step,step_use);
01018 DEF_LIST *deflist = Du_Mgr->Ud_Get_Def(step_use);
01019 deflist->Set_loop_stmt(do_loop);
01020 }
01021 INT num_loops = implied_dos->Elements();
01022 for (i=0; i<num_loops; i++) {
01023 WN *loop = loops[i];
01024 IO_Copy_Defs(IO_node,WN_end(loop),loops,num_loops);
01025 }
01026
01027 TY_IDX element_type;
01028 if (TY_kind(ST_type(array_st)) == KIND_POINTER) {
01029 element_type = TY_AR_etype(TY_pointed(ST_type(array_st)));
01030 } else {
01031 Is_True(TY_kind(ST_type(array_st)) == KIND_ARRAY,
01032 ("Non-array,non-pointer in Copy_Array"));
01033 element_type = TY_AR_etype(ST_type(array_st));
01034 }
01035 TYPE_ID machine_element_type = TY_mtype(element_type);
01036
01037
01038 OPCODE op_array = OPCODE_make_op(OPR_ARRAY,Pointer_type,MTYPE_V);
01039
01040 WN *array_base=dact->Dinfo()->Load_Distr_Array();
01041
01042 WN *local_base =
01043 LWN_CreateLdid(OPCODE_make_op(OPR_LDID,Pointer_type,Pointer_type),tmp_array_def);
01044 Du_Mgr->Add_Def_Use(tmp_array_def,local_base);
01045
01046
01047 WN *array_wn = WN_Create(op_array,1+2*array_dims);
01048 WN *local_wn = WN_Create(op_array,1+2*local_dims);
01049 WN_element_size(array_wn) = TY_size(element_type);
01050 WN_element_size(local_wn) = TY_size(element_type);
01051 WN_array_base(array_wn) = array_base;
01052 WN_array_base(local_wn) = local_base;
01053
01054 INT j=0;
01055 for (i=0; i<local_dims; i++) {
01056 if (const_dimensions) {
01057 while (const_dimensions[j]) j++;
01058 }
01059 WN *index = LWN_Copy_Tree(WN_array_index(orig_array,j));
01060 WN_array_index(local_wn,i) = index;
01061 IO_Copy_Defs(IO_node,index,loops,num_loops);
01062 WN_array_dim(local_wn,i) = dact->Array_Size_WN(j);
01063 j++;
01064 }
01065
01066 j=0;
01067 for (i=0; i<array_dims; i++) {
01068 WN_array_index(array_wn,i) = LWN_Copy_Tree(WN_array_index(orig_array,i));
01069 IO_Copy_Defs(IO_node,WN_array_index(array_wn,i),loops,num_loops);
01070 WN_array_dim(array_wn,i) = dact->Array_Size_WN(i);
01071 }
01072 for (i=0; i<WN_kid_count(array_wn); i++) {
01073 LWN_Set_Parent(WN_kid(array_wn,i),array_wn);
01074 }
01075 for (i=0; i<WN_kid_count(local_wn); i++) {
01076 LWN_Set_Parent(WN_kid(local_wn,i),local_wn);
01077 }
01078 WN *store;
01079 if (copy_in) {
01080 WN *value = LWN_CreateIload(
01081 OPCODE_make_op(OPR_ILOAD,machine_element_type,machine_element_type),
01082 0,element_type,Make_Pointer_Type(element_type),array_wn);
01083 if (ST_sclass(array_st) == SCLASS_FORMAL) {
01084 Create_formal_alias(Alias_Mgr,WN_st(array_base),array_base,value);
01085 } else if (WN_operator(array_base)==OPR_LDA) {
01086 Create_lda_array_alias(Alias_Mgr,array_base,value);
01087 } else {
01088 Create_unique_pointer_alias(Alias_Mgr,WN_st(array_base),array_base,value);
01089 }
01090 store = LWN_CreateIstore(
01091 OPCODE_make_op(OPR_ISTORE,MTYPE_V,machine_element_type),
01092 0,Make_Pointer_Type(element_type),value,local_wn);
01093 if (alias_host==NULL) {
01094 Create_unique_pointer_alias(Alias_Mgr,local_st,NULL, store);
01095 alias_host = store;
01096 } else {
01097 Copy_alias_info(Alias_Mgr, alias_host, store);
01098 }
01099
01100 LWN_Copy_Linenumber(IO_node,store);
01101 } else {
01102 WN *value = LWN_CreateIload(
01103 OPCODE_make_op(OPR_ILOAD,machine_element_type,machine_element_type),
01104 0,element_type,Make_Pointer_Type(element_type),local_wn);
01105 if (alias_host==NULL) {
01106 Create_unique_pointer_alias(Alias_Mgr,local_st,NULL, value);
01107 alias_host = value;
01108 } else {
01109 Copy_alias_info(Alias_Mgr, alias_host, value);
01110 }
01111
01112 store = LWN_CreateIstore(
01113 OPCODE_make_op(OPR_ISTORE,MTYPE_V,machine_element_type),
01114 0,Make_Pointer_Type(element_type),value,array_wn);
01115 if (ST_sclass(array_st) == SCLASS_FORMAL) {
01116 Create_formal_alias(Alias_Mgr,WN_st(array_base),array_base,store);
01117 } else if (WN_operator(array_base)==OPR_LDA) {
01118 Create_lda_array_alias(Alias_Mgr,array_base,store);
01119 } else {
01120 Create_unique_pointer_alias(Alias_Mgr,WN_st(array_base),array_base,store);
01121 }
01122 LWN_Copy_Linenumber(IO_node,store);
01123 }
01124 LWN_Insert_Block_Before(WN_do_body(do_loop),NULL,store);
01125
01126
01127
01128
01129 for (i=0; i<num_loops; i++) {
01130 WN *loop = loops[i];
01131 WN *implied_loop = implied_dos->Top_nth(i);
01132 TYPE_ID index_type = WN_rtype(WN_start(implied_loop));
01133 char name[20];
01134 sprintf(name,"copy_%d",i);
01135 WN_OFFSET index_var_num;
01136 ST *index_var_st;
01137 #ifdef _NEW_SYMTAB
01138 index_var_num = Create_Preg(index_type,name);
01139 #else
01140 index_var_num = Create_Preg(index_type,name,NULL);
01141 #endif
01142 index_var_st = MTYPE_To_PREG(index_type);
01143 Replace_Symbol(loop,
01144 SYMBOL(WN_st(WN_index(implied_loop)),
01145 WN_offset(WN_index(implied_loop)),
01146 index_type),
01147 SYMBOL(index_var_st,index_var_num,index_type),
01148 NULL,loop);
01149 }
01150
01151 Fix_Up_Loop_Info(IO_node,loops,num_loops);
01152
01153 CXX_DELETE(implied_dos,&LNO_local_pool);
01154 CXX_DELETE_ARRAY(loop_starts,&LNO_local_pool);
01155 CXX_DELETE_ARRAY(loop_steps,&LNO_local_pool);
01156 CXX_DELETE_ARRAY(loops,&LNO_local_pool);
01157 MEM_POOL_Pop(&LNO_local_pool);
01158 }
01159
01160
01161 extern void Fix_Up_Loop_Info(WN *IO_node, WN **loops, INT num_loops)
01162 {
01163 WN *enclosing_loop = LWN_Get_Parent(IO_node);
01164 INT depth = -1;
01165 while (enclosing_loop && (WN_opcode(enclosing_loop) != OPC_DO_LOOP)) {
01166 enclosing_loop = LWN_Get_Parent(enclosing_loop);
01167 }
01168 if (enclosing_loop) {
01169 depth = Do_Loop_Depth(enclosing_loop);
01170 }
01171 while (enclosing_loop) {
01172 if (WN_opcode(enclosing_loop) == OPC_DO_LOOP) {
01173 DO_LOOP_INFO *dli = (DO_LOOP_INFO *) WN_MAP_Get(LNO_Info_Map,
01174 enclosing_loop);
01175 dli->Is_Inner = FALSE;
01176 }
01177 enclosing_loop = LWN_Get_Parent(enclosing_loop);
01178 }
01179 for (INT i=0; i<num_loops; i++) {
01180 DO_LOOP_INFO *dli = (DO_LOOP_INFO *)
01181 CXX_NEW(DO_LOOP_INFO(&LNO_default_pool,NULL,NULL,NULL,FALSE,
01182 FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,TRUE) ,&LNO_default_pool);
01183 dli->Depth = depth+i+1;
01184 dli->Is_Backward = FALSE;
01185 dli->Has_Calls=FALSE;
01186 dli->Has_Unsummarized_Calls=FALSE;
01187 dli->Has_Gotos=FALSE;
01188 dli->Is_Inner = (i == (num_loops-1));
01189 dli->Has_Bad_Mem = FALSE;
01190 WN_MAP_Set(LNO_Info_Map,loops[i],(void *)dli);
01191 }
01192 Whack_Do_Loops(loops[0]);
01193 }
01194
01195
01196
01197 inline OPERATOR
01198 WN_opc_operator(WN *wn)
01199 {
01200 return WN_operator(wn);
01201 }
01202
01203
01204
01205
01206 static BOOL
01207 Is_In_Namelist_Stack(STACK_OF_WN *namelists, const char *name)
01208 {
01209
01210
01211
01212
01213 BOOL found = FALSE;
01214
01215 for (INT i = 0; !found && (i < namelists->Elements()); i++)
01216 {
01217 found =
01218 !strcmp(name,
01219 ST_name(WN_st(WN_kid0(WN_kid1(namelists->Bottom_nth(i))))));
01220 }
01221 return found;
01222 }
01223
01224
01225
01226
01227
01228 static void
01229 Get_IOL_Reshaped_Array_Ref(STACK_OF_REFERENCES *refs, WN *wn, BOOL in_implied_do,
01230 BOOL in_load, BOOL is_read)
01231 {
01232 OPCODE opcode = WN_opcode(wn);
01233 OPERATOR oper = OPCODE_operator(opcode);
01234 if ((oper == OPR_IO_ITEM) &&
01235 (WN_io_item(wn) == IOL_IMPLIED_DO)) {
01236 in_implied_do = TRUE;
01237 for (INT i=0; i<WN_kid_count(wn); i++) {
01238 Get_IOL_Reshaped_Array_Ref(refs,WN_kid(wn,i),in_implied_do, in_load, is_read);
01239 }
01240 } else if ((oper == OPR_LDA) || (oper == OPR_LDID)) {
01241 if (ST_is_reshaped_var(WN_st(wn))) {
01242 BOOL ref_is_loaded = in_load || !is_read;
01243 REF_TYPE ref_type;
01244 WN *parent = LWN_Get_Parent(wn);
01245 if (WN_operator(parent) == OPR_IO_ITEM) {
01246 ref_type = TOTAL_REF;
01247 } else if ((WN_operator(parent) == OPR_ARRAY) &&
01248 (wn == WN_array_base(parent))) {
01249 WN *grand_parent = LWN_Get_Parent(parent);
01250 OPCODE grand_op = WN_opcode(grand_parent);
01251 if (OPCODE_is_load(grand_op) ||
01252 ((OPCODE_operator(grand_op) == OPR_IO_ITEM) &&
01253 (WN_io_item(grand_parent) == IOL_VAR))) {
01254 if (in_implied_do) {
01255 ref_type = IMPLIED_DO_REF;
01256 } else {
01257 ref_type = SINGLE_ELEMENT_REF;
01258 }
01259 } else {
01260 ref_type = OTHER_REF;
01261 }
01262 } else {
01263 ref_type = OTHER_REF;
01264 }
01265 refs->Push(REFERENCE(wn,ref_type,ref_is_loaded));
01266 }
01267 } else if (OPCODE_is_load(opcode)) {
01268 in_load = TRUE;
01269 for (INT i=0; i<WN_kid_count(wn); i++) {
01270 Get_IOL_Reshaped_Array_Ref(refs,WN_kid(wn,i),in_implied_do, in_load,
01271 is_read);
01272 }
01273 } else {
01274 if (opcode == OPC_BLOCK) {
01275 WN *kid = WN_first (wn);
01276 while (kid) {
01277 Get_IOL_Reshaped_Array_Ref(refs,kid,in_implied_do, in_load, is_read);
01278 kid = WN_next(kid);
01279 }
01280 } else {
01281 for (INT i=0; i<WN_kid_count(wn); i++) {
01282 Get_IOL_Reshaped_Array_Ref(refs,WN_kid(wn,i),in_implied_do, in_load, is_read);
01283 }
01284 }
01285 }
01286 }
01287
01288
01289
01290 static void
01291 Get_IOS_Reshaped_Array_Refs(WN *io_stmt,
01292 STACK_OF_WN *namelists,
01293 STACK_OF_REFERENCES *refs)
01294 {
01295
01296
01297
01298
01299
01300
01301
01302 INT i;
01303 BOOL done;
01304
01305 Is_True(WN_opc_operator(io_stmt) == OPR_IO,
01306 ("Unexpected OPERATOR in Get_IOS_Reshaped_Array_Refs()"));
01307
01308 switch (WN_io_statement(io_stmt))
01309 {
01310 case IOS_NAMELIST:
01311 case IOS_CR_FWN:
01312 case IOS_CR_FRN:
01313
01314
01315
01316 for (done = FALSE, i = 2; !done && (i < WN_kid_count(io_stmt)); i++)
01317 {
01318 WN *ref = WN_kid0(WN_kid(io_stmt, i));
01319
01320 Is_True(WN_opc_operator(ref) == OPR_LDA ||
01321 WN_opc_operator(ref) == OPR_LDID,
01322 ("Unexpected OPERATOR in IOS_NAMELIST"));
01323
01324 if (ST_is_reshaped_var(WN_st(ref)))
01325 {
01326 namelists->Push(io_stmt);
01327 done = TRUE;
01328 }
01329 }
01330 break;
01331
01332 case IOS_DECODE:
01333 case IOS_ACCEPT:
01334 case IOS_READ:
01335 case IOS_CR_FRF:
01336 case IOS_CR_FRU:
01337 case IOS_CR_FWF:
01338 case IOS_CR_FWU:
01339 case IOS_ENCODE:
01340 case IOS_PRINT:
01341 case IOS_REWRITE:
01342 case IOS_TYPE:
01343 case IOS_WRITE:
01344
01345
01346
01347
01348
01349
01350 for (done = FALSE, i = 0; !done && (i < WN_kid_count(io_stmt)); i++)
01351 {
01352 WN *item = WN_kid(io_stmt, i);
01353
01354 if (WN_io_item(item) == IOF_NAMELIST_DIRECTED &&
01355 Is_In_Namelist_Stack(namelists, ST_name(WN_st(WN_kid0(item)))))
01356 {
01357 ErrMsgSrcpos(EC_LNO_Generic_Error, WN_Get_Linenum(io_stmt),
01358 "Cannot do IO with reshaped array in namelist\n");
01359 refs->Clear();
01360 done = TRUE;
01361 }
01362 else if (Is_IO_List_Item(item))
01363 {
01364 if ((WN_io_statement(io_stmt) == IOS_READ) ||
01365 (WN_io_statement(io_stmt) == IOS_CR_FRF) ||
01366 (WN_io_statement(io_stmt) == IOS_CR_FRU) ||
01367 (WN_io_statement(io_stmt) == IOS_ACCEPT) ||
01368 (WN_io_statement(io_stmt) == IOS_DECODE)) {
01369 Get_IOL_Reshaped_Array_Ref(refs, item, FALSE,FALSE,TRUE);
01370 } else {
01371 Get_IOL_Reshaped_Array_Ref(refs, item, FALSE,FALSE,FALSE);
01372 }
01373 }
01374 }
01375 break;
01376
01377 default:
01378
01379
01380 break;
01381 }
01382
01383 }
01384
01385
01386
01387