Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 00002 #include "defs.h" 00003 #include "glob.h" 00004 #include "config.h" 00005 #include "wn.h" 00006 #include "wn_util.h" 00007 #include "const.h" 00008 #include <cmplrs/rcodes.h> 00009 #include <upc_wn_util.h> 00010 #include <upc_symtab_utils.h> 00011 #include <stack> 00012 00013 extern void fdump_tree(FILE *f, WN *wn); 00014 00015 BOOL Fold_Keep_Shared_Tas = TRUE; 00016 00017 SPTR_OFFSET_ACCUMULATION_STACK sptr_off_accumulation_stack; 00018 SPTR_ACCUMULATION_STATE sptr_accumulation_state = NO_ACCUMULATION;; 00019 00020 std::stack<CONSISTENCY_class> consistency_stack; 00021 MEM_POOL consistency_pool; 00022 WN_MAP consistency_map; 00023 00024 00025 00026 static inline TYPE_ID 00027 Widen_Mtype (TYPE_ID t) 00028 { 00029 if (MTYPE_is_m(t)) 00030 return t; 00031 if (MTYPE_is_void(t) || t == MTYPE_BS) { 00032 Fail_FmtAssertion ("Widen_Mtype: for MTYPE_V or MTYPE_BS"); 00033 return t; 00034 } 00035 if (MTYPE_byte_size(t) >= 4) 00036 return t; 00037 return Mtype_TransferSize(MTYPE_I4, t); 00038 } 00039 00040 00041 INTRINSIC 00042 WN_Type_To_SyncIntrinsic(TYPE_ID mtype) { 00043 switch (mtype) { 00044 case MTYPE_I1: 00045 case MTYPE_I2: 00046 case MTYPE_I4: 00047 case MTYPE_I8: 00048 case MTYPE_U1: 00049 case MTYPE_U2: 00050 case MTYPE_U4: 00051 case MTYPE_U8: 00052 case MTYPE_A4: 00053 case MTYPE_A8: 00054 return INTRN_WAIT_SYNC_REG; 00055 00056 //WEI: There's no sync function for float and double, 00057 //use the general wait_syncnb instead 00058 case MTYPE_F4: 00059 //return INTRN_WAIT_SYNC_FLOAT; 00060 case MTYPE_F8: 00061 //return INTRN_WAIT_SYNC_DOUBLE; 00062 default: 00063 return INTRN_WAIT_SYNC_MEM; 00064 } 00065 } 00066 00067 00068 00069 INTRINSIC 00070 WN_Type_To_Intrinsic(OPERATOR opr, int mtype, int strict=1, BOOL phaseless = TRUE) { 00071 switch(opr) { 00072 case OPR_LDID: 00073 case OPR_ILOAD: 00074 case OPR_MLOAD: 00075 switch(mtype) { 00076 case MTYPE_I1: 00077 case MTYPE_I2: 00078 case MTYPE_I4: 00079 case MTYPE_I8: 00080 case MTYPE_U1: 00081 case MTYPE_U2: 00082 case MTYPE_U4: 00083 case MTYPE_U8: 00084 case MTYPE_A4: 00085 case MTYPE_A8: 00086 return strict ? (phaseless ? INTRN_GET_P_VAL : INTRN_SILD) : 00087 (phaseless ? INTRN_GET_NB_P_VAL : INTRN_SILD_NB); 00088 case MTYPE_F4: 00089 return phaseless ? INTRN_GET_P_FVAL : INTRN_SF4LD; 00090 case MTYPE_F8: 00091 return phaseless ? INTRN_GET_P_DVAL : INTRN_SF8LD; 00092 case MTYPE_F10: 00093 case MTYPE_F16: 00094 case MTYPE_FQ: 00095 case MTYPE_C4: 00096 case MTYPE_C8: 00097 case MTYPE_CQ: 00098 case MTYPE_BS: 00099 case MTYPE_M: 00100 return strict ? (phaseless ? INTRN_GET_P : INTRN_SMLD) : 00101 (phaseless ? INTRN_GET_NB_P : INTRN_SMLD_NB); 00102 default : 00103 Is_True(0, ("Wrong mtype in WN_Type_To_Intrinsic","")); 00104 } 00105 break; 00106 case OPR_ISTORE: 00107 case OPR_STID: 00108 case OPR_MSTORE: 00109 switch(mtype) { 00110 case MTYPE_I1: 00111 case MTYPE_I2: 00112 case MTYPE_I4: 00113 case MTYPE_I8: 00114 case MTYPE_U1: 00115 case MTYPE_U2: 00116 case MTYPE_U4: 00117 case MTYPE_U8: 00118 case MTYPE_A4: 00119 case MTYPE_A8: 00120 return strict ? (phaseless ? INTRN_PUT_P_VAL : INTRN_SIST ) : 00121 (phaseless ? INTRN_PUT_NB_P_VAL : INTRN_SIST_NB); 00122 00123 case MTYPE_F4: 00124 return (phaseless ? INTRN_PUT_P_FVAL : INTRN_SF4ST); 00125 00126 case MTYPE_F8: 00127 return phaseless ? INTRN_PUT_P_DVAL : INTRN_SF8ST ; 00128 case MTYPE_F10: 00129 case MTYPE_F16: 00130 case MTYPE_FQ: 00131 case MTYPE_C4: 00132 case MTYPE_C8: 00133 case MTYPE_CQ: 00134 case MTYPE_BS: 00135 case MTYPE_M: 00136 return strict ? (phaseless ? INTRN_PUT_P : INTRN_SMST) : 00137 (phaseless ? INTRN_PUT_NB_P : INTRN_SMST_NB); 00138 default : 00139 Is_True(0, ("Wrong mtype in WN_Type_To_Intrinsic","")); 00140 } 00141 break; 00142 default: 00143 Is_True(0, ("Operator not supported in WFE_Type_To_Intrinsic","")); 00144 } 00145 00146 /* NOTREACHED */ 00147 Is_True(0, ("Programming error.","")); 00148 return INTRINSIC_INVALID; 00149 } 00150 00151 00152 // For opr == OPR_EQ, bsize and idx1 are either shared_ptr_idx or pshared 00153 INTRINSIC 00154 WN_Operator_To_Intrinsic (OPERATOR opr, INT bsize = 0, INT idx1 = 0) 00155 { 00156 switch (opr) { 00157 case OPR_ADD: 00158 case OPR_SUB: 00159 switch(bsize) { 00160 case 0: 00161 return INTRN_ADD_PI; 00162 case 1: 00163 return INTRN_ADD_P1; 00164 default: 00165 return INTRN_SPTRADD; 00166 } 00167 break; 00168 case OPR_EQ: 00169 if (idx1 == shared_ptr_idx) { 00170 return (bsize == shared_ptr_idx) ? INTRN_EQ_S_S : 00171 (bsize == pshared_ptr_idx) ? INTRN_EQ_S_P : INTRN_ISNULL_S; 00172 } else if (idx1 == pshared_ptr_idx) 00173 return (bsize == shared_ptr_idx) ? INTRN_EQ_S_P : 00174 (bsize == pshared_ptr_idx) ? INTRN_EQ_P_P : INTRN_ISNULL_P; 00175 else 00176 return bsize == shared_ptr_idx ? INTRN_ISNULL_S : INTRN_ISNULL_P; 00177 00178 break; 00179 default: 00180 Is_True(0, ("","")); 00181 } 00182 00183 00184 00185 return INTRN_SPTRADD; 00186 } 00187 00188 00189 00190 static WN* 00191 Spill_And_Take_Address(WN *wn) { 00192 00193 WN *result; 00194 TY_IDX spill_ty; 00195 00196 if(WN_operator(wn) == OPR_LDA) 00197 return wn; 00198 else if(WN_operator(wn) == OPR_TAS) { 00199 wn = Strip_TAS(wn); 00200 } 00201 00202 switch(WN_operator(wn)) { 00203 case OPR_ILOAD: 00204 spill_ty = WN_field_id(wn) == 0 ? WN_ty(wn) : Get_Field_Type(WN_ty(wn), WN_field_id(wn)); 00205 if(WN_field_id(wn) && Type_Is_Shared_Ptr(spill_ty)) 00206 spill_ty = TY_To_Sptr_Idx(spill_ty); 00207 break; 00208 default: 00209 spill_ty = MTYPE_To_TY(WN_rtype(wn)); 00210 break; 00211 } 00212 00213 TYPE_ID desc = TY_mtype(spill_ty); 00214 result = WN_CreateBlock (); 00215 ST *handle_st = Gen_Temp_Symbol(spill_ty, (char*) ".spillstoreparm"); 00216 WN_INSERT_BlockLast (result, WN_Stid (desc, 0, handle_st, spill_ty, wn)); 00217 result = WN_CreateComma (OPR_COMMA, Pointer_Mtype, MTYPE_V, result, 00218 WN_Lda(Pointer_Mtype, 0, handle_st, 0)); 00219 return result; 00220 } 00221 00222 static 00223 TYPE_ID Shared_Load_Extend_Mtyp (TYPE_ID typ) 00224 { 00225 BOOL _64_bit_target = TY_size(MTYPE_To_TY(Pointer_type)) > 4; 00226 switch (typ) { 00227 case MTYPE_B: 00228 case MTYPE_I1: 00229 case MTYPE_I2: 00230 case MTYPE_I4: 00231 case MTYPE_U1: 00232 case MTYPE_U2: 00233 case MTYPE_U4: 00234 if(_64_bit_target) 00235 return MTYPE_I8; 00236 else 00237 return MTYPE_I4; 00238 case MTYPE_I8: 00239 case MTYPE_U8: 00240 if(_64_bit_target) 00241 return MTYPE_I8; 00242 else 00243 Is_True(0,("","")); 00244 00245 default: 00246 return typ; 00247 } 00248 00249 } 00250 00251 00252 00253 static CONSISTENCY_class 00254 Get_Access_Consistency (TY_IDX idx) { 00255 00256 if (idx == 0) 00257 return consistency_stack.top(); 00258 00259 switch(TY_kind(idx)) { 00260 case KIND_POINTER: 00261 idx = TY_pointed(idx); 00262 break; 00263 case KIND_ARRAY: 00264 idx = Get_Inner_Array_Type(idx); 00265 break; 00266 } 00267 00268 return TY_is_strict (idx) ? STRICT_CONSISTENCY : 00269 (TY_is_relaxed(idx) ? RELAXED_CONSISTENCY : consistency_stack.top()); 00270 } 00271 00272 00273 00274 WN* 00275 WN_Create_Shared_Store (WN *st, BOOL src_is_shared, WN_OFFSET xtra_offst, 00276 BOOL has_offt, WN *offt) { 00277 00278 ST *op_st = 0, *handle_st; 00279 WN *arg0, *call_wn; 00280 WN *wn0, *wn1, *init_wn = 0, *handle_wn; 00281 TYPE_ID rtype, desc; 00282 WN_OFFSET offset; 00283 CONSISTENCY_class consistency = STRICT_CONSISTENCY; 00284 TY_IDX handle_ty_idx; 00285 TY_IDX actual_shared_ptr_idx; 00286 rtype = ((WN_desc(st) == MTYPE_V) ? MTYPE_M : WN_desc(st)) ; 00287 //desc = WN_desc(st); 00288 int strictw; 00289 int transfer_size = 0; 00290 WN *spilled_preg_ldid = 0; 00291 00292 BOOL _64_bit_target = TY_size(MTYPE_To_TY(Pointer_type)) > 4; 00293 00294 // fprintf(stderr, "Shared Store IN\n"); 00295 // fdump_tree(stderr, st); 00296 00297 00298 actual_shared_ptr_idx = pshared_ptr_idx; 00299 00300 switch (WN_operator(st)) { 00301 case OPR_STID: 00302 op_st = WN_st(st); 00303 consistency = Get_Access_Consistency(WN_ty(st)); 00304 if(TY_kind(WN_ty(st)) == KIND_POINTER && TY_is_shared(WN_ty(st))) { 00305 if(Type_Is_Shared_Ptr(TY_pointed(WN_ty(st)))) { 00306 rtype = TY_mtype(TY_To_Sptr_Idx(TY_pointed(WN_ty(st)))); 00307 transfer_size = TY_size(TY_To_Sptr_Idx(TY_pointed(WN_ty(st)))); 00308 } else 00309 transfer_size = TY_size(WN_ty(st)); 00310 } 00311 break; 00312 case OPR_ISTORE: 00313 case OPR_MSTORE: { 00314 arg0 = WN_kid1(st); 00315 TY_IDX pt_idx = TY_pointed(WN_ty(st)); 00316 consistency = Get_Access_Consistency(WN_ty(arg0)); 00317 if(Type_Is_Shared_Ptr(pt_idx)) { 00318 if(Type_Is_Shared_Ptr(pt_idx, TRUE)) { 00319 //ptr to shared - need to adjust size to sizeof(shared_ptr) 00320 rtype = TY_mtype(TY_To_Sptr_Idx(TY_pointed(WN_ty(st)))); 00321 transfer_size = TY_size(TY_To_Sptr_Idx(TY_pointed(WN_ty(st)))); 00322 } else if(TY_kind(pt_idx) == KIND_STRUCT) { 00323 if(WN_field_id(st)) { 00324 rtype = TY_mtype(Get_Field_Type(pt_idx, WN_field_id(st))); 00325 transfer_size = TY_size(Get_Field_Type(pt_idx, WN_field_id(st))); 00326 } else { 00327 rtype = MTYPE_M; 00328 transfer_size = TY_size(pt_idx); 00329 } 00330 } 00331 } 00332 arg0 = Strip_TAS(arg0); 00333 break; 00334 } 00335 default: 00336 Is_True(0,("","")); 00337 00338 } 00339 00340 actual_shared_ptr_idx = TY_To_Sptr_Idx(WN_ty(st)); 00341 if(TY_is_shared(WN_ty(st)) && TY_kind(WN_ty(st)) != KIND_SCALAR && TY_kind(WN_ty(st)) != KIND_STRUCT) { 00342 // rtype = TY_mtype(actual_shared_ptr_idx) 00343 ; 00344 // src_is_shared = TRUE; 00345 } 00346 00347 00348 if(!_64_bit_target && (rtype == MTYPE_I8 || rtype == MTYPE_A8 || rtype == MTYPE_U8) ) { 00349 transfer_size = TY_size(MTYPE_To_TY(rtype)); 00350 rtype = MTYPE_M; 00351 } else if(consistency == RELAXED_CONSISTENCY && (rtype == MTYPE_F4 || rtype == MTYPE_F8)) { 00352 transfer_size = TY_size(MTYPE_To_TY(rtype)); 00353 rtype = MTYPE_M; 00354 } 00355 00356 00357 // if (Get_Type_Block_Size(WN_ty(st)) > 1) 00358 // actual_shared_ptr_idx = shared_ptr_idx; 00359 00360 00361 handle_ty_idx = (rtype == MTYPE_M) ? upc_hsync_mem_ty : upc_hsync_reg_ty; 00362 desc = (consistency == STRICT_CONSISTENCY || rtype == MTYPE_F4 || rtype == MTYPE_F8) ? 00363 MTYPE_V : TY_mtype(handle_ty_idx); 00364 offset = xtra_offst; 00365 // shared scalar of field of shared struct 00366 if (op_st) { 00367 if(WN_field_id(st) >1) 00368 offset += Adjust_Field_Offset(ST_type(op_st), WN_field_id(st)); 00369 else 00370 offset += WN_offset(st); 00371 00372 arg0 = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), 00373 WN_CreateLdid(OPR_LDID, TY_mtype(actual_shared_ptr_idx), 00374 TY_mtype(actual_shared_ptr_idx), 00375 0 /*offset*/, ST_st_idx(*op_st),actual_shared_ptr_idx, 0), 00376 actual_shared_ptr_idx, WN_PARM_BY_VALUE); 00377 00378 } else { 00379 arg0 = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), arg0, actual_shared_ptr_idx, 00380 WN_PARM_BY_VALUE); 00381 } 00382 00383 00384 00385 call_wn = WN_Create (OPR_INTRINSIC_CALL, desc, desc, 00386 (rtype == MTYPE_F4 || rtype == MTYPE_F8 || src_is_shared) ? 3 : 4); 00387 WN_intrinsic(call_wn) = WN_Type_To_Intrinsic(OPR_STID, 00388 src_is_shared ? MTYPE_M : rtype, 00389 (consistency == STRICT_CONSISTENCY), 00390 (actual_shared_ptr_idx == pshared_ptr_idx)); 00391 if (src_is_shared) 00392 WN_intrinsic(call_wn) = INTRN_UPC_MEMCPY; 00393 00394 WN_kid0 (call_wn) = arg0; 00395 00396 if (!src_is_shared) 00397 WN_kid1(call_wn) = WN_CreateParm(Integer_type, 00398 has_offt ? offt : 00399 WN_Intconst(Integer_type, offset), 00400 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00401 else 00402 WN_kid1(call_wn) = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), Strip_TAS(WN_kid0(st)), 00403 actual_shared_ptr_idx, WN_PARM_BY_VALUE); 00404 00405 if (src_is_shared) { 00406 WN_kid2(call_wn) = WN_CreateParm(Integer_type, 00407 (WN_operator(st) == OPR_MSTORE || WN_operator(st) == OPR_ISTORE ) ? 00408 WN_COPY_Tree(WN_kid2(st)) : 00409 WN_Intconst(Integer_type, 00410 TY_size(actual_shared_ptr_idx)), 00411 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00412 } else { 00413 WN *value = WN_kid0(st); 00414 TY_IDX parm_ty_idx = (WN_ty(value)) ? WN_ty(value) : MTYPE_To_TY(WN_rtype(value)); 00415 if(TY_kind(parm_ty_idx) != KIND_SCALAR && Type_Is_Shared_Ptr(parm_ty_idx)) 00416 transfer_size = TY_size(TY_To_Sptr_Idx(parm_ty_idx)); 00417 value = Strip_TAS(value); 00418 //WEI: the old code was testing WN_rtype(st), fix it here 00419 if (WN_rtype(value) != MTYPE_M && rtype != MTYPE_M) 00420 WN_kid2 (call_wn) = WN_CreateParm(Mtype_comparison(WN_rtype(value)), value, 00421 parm_ty_idx, WN_PARM_BY_VALUE); 00422 else { // need to extract the address of the symbol accessed by value 00423 if (WN_operator(value) == OPR_LDID && WN_st_idx(value) != 0) { 00424 ST *tst; 00425 //need to check here for the special case of ldid of return_preg 00426 //can't take it's address - spill 00427 if(ST_class(WN_st(value)) == CLASS_PREG) { 00428 // fprintf(stderr, "BEFORE SPILL \n"); 00429 // fdump_tree(stderr, value); 00430 // value = Spill_Shared_Load(value); 00431 // fprintf(stderr, "AFTER SPILL \n"); 00432 // fdump_tree(stderr, value); 00433 // tst = WN_st(WN_kid1(value)); 00434 // spilled_preg_ldid = value; 00435 Is_True(0,("","")); 00436 } else 00437 tst = WN_st(value); 00438 00439 00440 WN_kid2(call_wn) = WN_CreateParm(Pointer_Mtype, 00441 WN_Lda(Pointer_Mtype, 0, tst, 0), 00442 MTYPE_To_TY(Pointer_Mtype), WN_PARM_BY_VALUE); 00443 } else if(WN_operator(value) == OPR_COMMA && 00444 WN_operator(WN_kid1(value)) == OPR_LDID){ 00445 WN *kid1 = WN_kid1(value); 00446 WN *kid0 = WN_kid0(value); 00447 Is_True(WN_st(kid1), ("","")); 00448 00449 value = WN_CreateComma (OPR_COMMA, Pointer_Mtype, MTYPE_V, 00450 kid0, WN_Lda(Pointer_Mtype, 0, WN_st(kid1), 0)); 00451 WN_kid2(call_wn) = WN_CreateParm(Pointer_Mtype, value, 00452 MTYPE_To_TY(Pointer_Mtype), WN_PARM_BY_VALUE); 00453 } else if (WN_operator(value) == OPR_INTCONST) { 00454 TYPE_ID desc = WN_rtype(value); 00455 Is_True((!_64_bit_target && TY_size(MTYPE_To_TY(desc)) > 4) || 00456 /* check for NULL ptr assignment */ 00457 (WN_operator(st) != OPR_STID && Type_Is_Shared_Ptr(TY_pointed(WN_ty(st)), TRUE)), ("","")); 00458 00459 //NULL ptr assignment 00460 if (TY_kind(WN_ty(st)) == KIND_POINTER && Type_Is_Shared_Ptr(TY_pointed(WN_ty(st)), TRUE)) { 00461 return WN_SetNull_Sptr(st); 00462 } 00463 //this is for constants assigned to 64 bit int values on 32 bit targets 00464 //spill the const into a variable and pass the address into the assignment. 00465 init_wn = WN_CreateBlock (); 00466 handle_st = Gen_Temp_Symbol(MTYPE_To_TY(desc), (char*) ".spill64ct"); 00467 WN_INSERT_BlockLast (init_wn, WN_Stid (desc, 0, handle_st, MTYPE_To_TY(desc), value)); 00468 WN_kid2(call_wn) = WN_CreateParm(Pointer_Mtype, WN_Lda(Pointer_Mtype, 0, handle_st, 0), 00469 MTYPE_To_TY(Pointer_Mtype), WN_PARM_BY_VALUE); 00470 } else { 00471 WN_kid2(call_wn) = WN_CreateParm(Pointer_Mtype, Spill_And_Take_Address(value), 00472 MTYPE_To_TY(Pointer_Mtype), WN_PARM_BY_VALUE); 00473 00474 } 00475 } 00476 } 00477 00478 if (rtype != MTYPE_F8 && rtype != MTYPE_F4 && !src_is_shared ) { 00479 Is_True((rtype == MTYPE_M && transfer_size != 0) || rtype != MTYPE_M, ("Illegal transfer size for remote store","")); 00480 WN_kid3(call_wn) = WN_CreateParm(Integer_type, 00481 (WN_operator(st) == OPR_MSTORE) ? WN_COPY_Tree(WN_kid2(st)): 00482 WN_Intconst(Integer_type, (rtype == MTYPE_M) ? transfer_size : TY_size(MTYPE_To_TY(rtype))), 00483 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00484 00485 } 00486 if(consistency == RELAXED_CONSISTENCY && !src_is_shared && 00487 //no NB puts for FP 00488 rtype != MTYPE_F4 && rtype != MTYPE_F8) { 00489 TYPE_ID hdesc = TY_mtype(handle_ty_idx); 00490 wn1 = WN_Ldid (hdesc, -1, Return_Val_Preg, handle_ty_idx); 00491 if(!init_wn) 00492 init_wn = WN_CreateBlock (); 00493 WN_INSERT_BlockLast (init_wn, call_wn); 00494 init_wn = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, init_wn, wn1); 00495 wn0 = WN_CreateBlock(); 00496 call_wn = WN_Create (OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V, 1); 00497 WN_intrinsic(call_wn) = WN_Type_To_SyncIntrinsic(MTYPE_M); 00498 00499 wn1 = WN_CreateBlock(); 00500 00501 handle_st = Gen_Temp_Symbol(handle_ty_idx, (char*) ".Msync"); 00502 WN_INSERT_BlockLast (wn1, WN_Stid (hdesc, 0, handle_st, handle_ty_idx, init_wn)); 00503 00504 handle_wn = WN_CreateLdid(OPR_LDID, hdesc,hdesc, 00505 ST_ofst(handle_st), handle_st, handle_ty_idx, 0); 00506 00507 wn1 = WN_CreateComma (OPR_COMMA, hdesc, MTYPE_V, wn1, handle_wn); 00508 WN_kid0(call_wn) = WN_CreateParm(hdesc, wn1, handle_ty_idx, WN_PARM_BY_VALUE); 00509 WN_INSERT_BlockLast (wn0, call_wn); 00510 call_wn = wn0; 00511 } else if (init_wn) { 00512 //this should happen only for strict puts with long long cts as srcs 00513 00514 WN_INSERT_BlockLast (init_wn, call_wn); 00515 call_wn = init_wn; 00516 } 00517 00518 return call_wn; 00519 00520 } 00521 00522 00523 00524 00525 WN* 00526 WN_Create_Shared_Load( WN *ld, 00527 WN *dest, 00528 BOOL is_struct, 00529 WN_OFFSET xtra_offst, 00530 TY_IDX access_ty, 00531 BOOL has_off, WN *off_wn) 00532 { 00533 WN *call_wn; 00534 WN *src, *dst, *offt, *size; 00535 00536 WN *init_wn = 0, *wn1 = 0, *wn2 = 0, *wn3 = 0; 00537 WN *handle_wn = 0, *wn0 = 0; 00538 INTRINSIC iop; 00539 TY_IDX desc_ty_idx; 00540 TY_IDX orig_ty_idx; 00541 TYPE_ID hdesc, rtype, desc; 00542 UINT orig_field_id = 0; 00543 UINT orig_offset = 0; 00544 CONSISTENCY_class consistency; 00545 TY_IDX handle_ty_idx = 0; 00546 ST *ret_st = 0; 00547 ST *handle_st = 0; 00548 WN *ldc; 00549 TY_IDX ret_ty; 00550 TY_IDX sptr_idx = 0; 00551 UINT tmp_field_id = 0; 00552 WN_OFFSET offset = 0; 00553 BOOL _64_bit_target = TY_size(MTYPE_To_TY(Pointer_type)) > 4; 00554 00555 // fprintf(stderr,"Shared Load IN\n"); 00556 // fdump_tree(stderr,ld); 00557 00558 consistency = Get_Access_Consistency(WN_ty(ld)); 00559 rtype = WN_rtype(ld); 00560 desc = WN_desc(ld); 00561 00562 if(WN_operator(ld) == OPR_TAS) 00563 ld = Strip_TAS(ld); 00564 00565 switch (WN_operator(ld)) { 00566 case OPR_LDID: 00567 ldc = WN_COPY_Tree(ld); 00568 orig_field_id = WN_field_id(ldc); 00569 00570 offset = WN_field_id(ld) > 1 ? Adjust_Field_Offset(WN_ty(ld), WN_field_id(ld)) : WN_offset(ld) + xtra_offst; 00571 00572 // modify on the fly the type of the argument, otherwise 00573 // can't create parm node 00574 // have to set it back at the end 00575 sptr_idx = TY_To_Sptr_Idx(WN_ty(ld)); 00576 WN_set_ty(ldc, sptr_idx); 00577 WN_set_rtype(ldc, TY_mtype(sptr_idx)); 00578 WN_set_desc (ldc, TY_mtype(sptr_idx)); 00579 WN_set_field_id(ldc, 0); 00580 WN_offset(ldc) = 0; 00581 ret_ty = WN_object_ty(ld); 00582 //shared ptr to shared 00583 if ((TY_kind(WN_ty(ld)) == KIND_POINTER || 00584 TY_kind(WN_ty(ld)) == KIND_ARRAY ) && TY_is_shared(WN_ty(ld))) 00585 { 00586 TY_IDX tmp_idx = WN_ty(ld); 00587 if(WN_field_id(ld)) 00588 tmp_idx = Get_Field_Type(tmp_idx, WN_field_id(ld)); 00589 if(TY_kind(tmp_idx) == KIND_POINTER) { 00590 if (Type_Is_Shared_Ptr(TY_pointed(tmp_idx))) { 00591 tmp_idx = TY_pointed(tmp_idx); 00592 rtype = desc = TY_mtype(TY_To_Sptr_Idx(tmp_idx)); 00593 is_struct = (rtype == MTYPE_M); 00594 ret_ty = TY_To_Sptr_Idx(tmp_idx); 00595 } else { 00596 ret_ty = Make_Pointer_Type(TY_pointed(tmp_idx)); 00597 rtype = desc = TY_mtype(ret_ty); 00598 } 00599 } else if(TY_kind(tmp_idx) == KIND_ARRAY) { 00600 Is_True(0,("","")); 00601 } 00602 00603 } else if (Type_Is_Shared_Ptr(ret_ty, TRUE)) { 00604 ret_ty = TY_To_Sptr_Idx(ret_ty); 00605 rtype = desc = TY_mtype(ret_ty); 00606 is_struct = (rtype == MTYPE_M); 00607 } 00608 00609 break; 00610 00611 case OPR_MLOAD: 00612 case OPR_ILOAD: 00613 ldc = WN_COPY_Tree(WN_kid0(ld)); 00614 // fdump_tree(stderr, ldc); 00615 offset = WN_offset(ld) + xtra_offst; 00616 if (WN_field_id(ld)) { 00617 ret_ty = FLD_type(FLD_get_to_field(WN_object_ty(ld), WN_field_id(ld), tmp_field_id)); 00618 } else 00619 ret_ty = WN_object_ty(ld); 00620 00621 sptr_idx = (WN_operator(ld) == OPR_ILOAD) ? TY_To_Sptr_Idx(WN_load_addr_ty(ld)) : TY_To_Sptr_Idx(WN_ty(ld)); 00622 00623 if((TY_is_shared(WN_ty(ld)) && 00624 (TY_kind(WN_ty(ld)) == KIND_POINTER ||TY_kind(WN_ty(ld)) == KIND_ARRAY)) 00625 // && !WN_field_id(ld) 00626 ) { 00627 TY_IDX tmp_idx = ret_ty; 00628 if(TY_kind(tmp_idx) == KIND_POINTER) { 00629 if (Type_Is_Shared_Ptr(TY_pointed(tmp_idx))) { 00630 tmp_idx = TY_pointed(tmp_idx); 00631 rtype = desc = TY_mtype(TY_To_Sptr_Idx(tmp_idx)); 00632 is_struct = (rtype == MTYPE_M); 00633 ret_ty = TY_To_Sptr_Idx(tmp_idx); 00634 } else { 00635 ret_ty = Make_Pointer_Type(TY_pointed(tmp_idx)); 00636 rtype = desc = TY_mtype(ret_ty); 00637 } 00638 } else if(TY_kind(tmp_idx) == KIND_ARRAY) { 00639 Is_True(0,("","")); 00640 } 00641 } if(Type_Is_Shared_Ptr(ret_ty, TRUE)) { 00642 ret_ty = TY_To_Sptr_Idx(ret_ty); 00643 rtype = desc = TY_mtype(ret_ty); 00644 is_struct = (rtype == MTYPE_M); 00645 } 00646 00647 break; 00648 00649 case OPR_COMMA: 00650 Is_True(WN_rtype(ld) == TY_mtype(shared_ptr_idx) || WN_rtype(ld) == TY_mtype(pshared_ptr_idx), 00651 ("Bad rtype for shared ld src","")); 00652 ldc = WN_COPY_Tree(ld); 00653 offset += xtra_offst; 00654 ret_ty = access_ty; 00655 sptr_idx = TY_To_Sptr_Idx(WN_ty(WN_kid1(ld))); 00656 break; 00657 default: 00658 Is_True(0,("Not implemented yet","")); 00659 } 00660 00661 if (is_struct) { 00662 rtype = MTYPE_M; 00663 desc = MTYPE_M; 00664 } else if (!_64_bit_target && TY_size(MTYPE_To_TY(rtype)) > 4 && rtype != MTYPE_F8) 00665 { 00666 rtype = MTYPE_M; 00667 desc = MTYPE_M; 00668 is_struct = TRUE; 00669 } else 00670 if ((rtype == MTYPE_F8 || rtype == MTYPE_F4) && consistency == RELAXED_CONSISTENCY) { 00671 rtype = MTYPE_M; 00672 desc = MTYPE_M; 00673 is_struct = TRUE; 00674 // consistency = STRICT_CONSISTENCY; 00675 } 00676 00677 iop = WN_Type_To_Intrinsic(OPR_LDID , dest ? MTYPE_M : rtype, 00678 consistency == STRICT_CONSISTENCY, (sptr_idx == pshared_ptr_idx)); 00679 if (consistency == STRICT_CONSISTENCY) { 00680 /* strict load -> blocking call */ 00681 call_wn = WN_Create (OPR_INTRINSIC_CALL, 00682 (rtype == MTYPE_M) ? MTYPE_V : Shared_Load_Extend_Mtyp(rtype), 00683 (rtype == MTYPE_M) ? MTYPE_V : Shared_Load_Extend_Mtyp(desc), 00684 (rtype == MTYPE_M || dest) ? 4 : 00685 (rtype == MTYPE_F4 || rtype == MTYPE_F8) ? 2 : 3); 00686 } else { 00687 /* relaxed load - non-blocking load */ 00688 if (rtype < MTYPE_F8) { 00689 hdesc = upc_hsync_reg_ty ? TY_mtype (upc_hsync_reg_ty) : MTYPE_I8; 00690 handle_ty_idx = upc_hsync_reg_ty ? upc_hsync_reg_ty : MTYPE_To_TY(MTYPE_I8); 00691 } else { 00692 hdesc = upc_hsync_mem_ty ? TY_mtype (upc_hsync_mem_ty) : MTYPE_I8; 00693 handle_ty_idx = upc_hsync_mem_ty ? upc_hsync_mem_ty : MTYPE_To_TY(MTYPE_I8); 00694 } 00695 call_wn = WN_Create (OPR_INTRINSIC_CALL, hdesc, hdesc, 00696 (rtype == MTYPE_M) ? 4 : 00697 (rtype == MTYPE_F4 || rtype == MTYPE_F8) ? 2 : 3); 00698 } 00699 00700 WN_intrinsic(call_wn) = iop; 00701 00702 if(has_off) 00703 offt = WN_CreateParm(Integer_type, off_wn, MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00704 else 00705 offt = WN_CreateParm(Integer_type, WN_Intconst(Integer_type, offset), 00706 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00707 00708 size = WN_CreateParm(Integer_type, (WN_operator(ld)) == OPR_MLOAD ? WN_COPY_Tree(WN_kid1(ld)) : 00709 WN_Intconst(Integer_type, 00710 dest ? (access_ty ? TY_size(access_ty) :TY_size(TY_pointed(WN_ty(dest)))) : 00711 TY_size(ret_ty)), 00712 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00713 src = WN_CreateParm(TY_mtype(sptr_idx), Strip_TAS(ldc), 00714 sptr_idx, WN_PARM_BY_VALUE); 00715 00716 00717 if(TY_kind(ret_ty) == KIND_SCALAR){ 00718 ret_ty = MTYPE_To_TY(TY_mtype(ret_ty)); 00719 } else if(TY_kind(ret_ty) == KIND_STRUCT && TY_is_shared(ret_ty)) 00720 // Is_True(0,("","")) 00721 ; 00722 00723 if (dest) { 00724 WN_kid0(call_wn) = WN_CreateParm(Pointer_Mtype, WN_COPY_Tree(dest), MTYPE_To_TY(Pointer_Mtype), 00725 WN_PARM_BY_VALUE); 00726 WN_kid1(call_wn) = src; 00727 WN_kid2(call_wn) = offt; 00728 WN_kid3(call_wn) = size; 00729 if(consistency == STRICT_CONSISTENCY) 00730 return call_wn; 00731 } else { 00732 // for shared ptr to shared 00733 if(is_struct || (rtype == MTYPE_M && desc == MTYPE_M)) { 00734 Is_True(ret_ty == shared_ptr_idx || ret_ty == pshared_ptr_idx || 00735 (!_64_bit_target && TY_size(ret_ty) > 4) || 00736 (consistency == RELAXED_CONSISTENCY && 00737 (TY_mtype(ret_ty) == MTYPE_F4 || TY_mtype(ret_ty) == MTYPE_F8)) , ("","")); 00738 00739 00740 //the type of the temp is given by the the type of the point-to 00741 //type of the load 00742 TY_IDX ret_ty1 = WN_ty(ld); 00743 switch(TY_kind(ret_ty1)) { 00744 case KIND_POINTER: 00745 ret_ty1 = TY_To_Sptr_Idx(TY_pointed(ret_ty1)); 00746 break; 00747 case KIND_ARRAY: 00748 Is_True(0,("","")); 00749 break; 00750 case KIND_SCALAR: 00751 case KIND_STRUCT: 00752 ret_ty1 = ret_ty; 00753 break; 00754 default: 00755 Is_True(0,("","")); 00756 00757 } 00758 ret_st = Gen_Temp_Symbol(ret_ty1, (char*) ".spillld"); 00759 WN_kid0(call_wn) = WN_CreateParm(Pointer_Mtype, WN_Lda(Pointer_Mtype, 0, ret_st,0), 00760 MTYPE_To_TY(Pointer_Mtype), 00761 WN_PARM_BY_VALUE); 00762 WN_kid1(call_wn) = src; 00763 WN_kid2(call_wn) = offt; 00764 WN_kid3(call_wn) = size; 00765 } else { 00766 WN_kid0(call_wn) = src; 00767 WN_kid1(call_wn) = offt; 00768 } 00769 } 00770 00771 00772 00773 00774 00775 init_wn = WN_CreateBlock (); 00776 WN_INSERT_BlockLast (init_wn, call_wn); 00777 00778 00779 if (rtype < MTYPE_M) 00780 if( consistency == STRICT_CONSISTENCY) 00781 wn1 = WN_Ldid (rtype, -1, Return_Val_Preg, ret_ty); 00782 else { 00783 wn1 = WN_Ldid (TY_mtype(handle_ty_idx), -1, Return_Val_Preg, handle_ty_idx); 00784 } 00785 else { 00786 if(consistency == RELAXED_CONSISTENCY) 00787 wn1 = WN_Ldid (TY_mtype(handle_ty_idx), -1, Return_Val_Preg, handle_ty_idx); 00788 else { 00789 Is_True(ret_st, ("","")); 00790 return WN_CreateComma(OPR_COMMA, TY_mtype(ret_ty), MTYPE_V, init_wn, 00791 WN_Ldid (TY_mtype(ret_ty), 0, ret_st, ret_ty)); 00792 } 00793 } 00794 00795 switch (rtype) { 00796 case MTYPE_B: 00797 case MTYPE_I1: 00798 case MTYPE_I2: 00799 case MTYPE_I4: 00800 case MTYPE_I8: 00801 case MTYPE_U1: 00802 case MTYPE_U2: 00803 case MTYPE_U4: 00804 case MTYPE_U8: 00805 WN_kid2(call_wn) = size; 00806 break; 00807 default: 00808 break; 00809 } 00810 00811 00812 if (consistency == STRICT_CONSISTENCY) { 00813 call_wn = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, init_wn, wn1); 00814 // Is_True(rtype == MTYPE_M, ("","")); 00815 goto spill; 00816 } else { 00817 init_wn = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, init_wn, wn1); 00818 wn0 = WN_CreateBlock(); 00819 call_wn = WN_Create (OPR_INTRINSIC_CALL, (rtype < MTYPE_M) ? rtype : MTYPE_V, MTYPE_V, 1); 00820 WN_intrinsic(call_wn) = WN_Type_To_SyncIntrinsic(rtype); 00821 //WEI: fix rtype here, since we use wait_syncnb for float and double now 00822 if (WN_intrinsic(call_wn) == INTRN_WAIT_SYNC_MEM) { 00823 WN_set_rtype(call_wn, MTYPE_V); 00824 } 00825 00826 wn1 = WN_CreateBlock(); 00827 00828 handle_st = Gen_Temp_Symbol(handle_ty_idx, (char*) ".Msync"); 00829 WN_INSERT_BlockLast (wn1, WN_Stid (TY_mtype(handle_ty_idx), 0, handle_st, 00830 handle_ty_idx, init_wn)); 00831 00832 00833 handle_wn = WN_CreateLdid(OPR_LDID, hdesc, hdesc, ST_ofst(handle_st), handle_st, handle_ty_idx, 0); 00834 00835 wn1 = WN_CreateComma (OPR_COMMA, hdesc, MTYPE_V, wn1, handle_wn); 00836 WN_kid0(call_wn) = WN_CreateParm(hdesc, wn1, handle_ty_idx, WN_PARM_BY_VALUE); 00837 WN_INSERT_BlockLast (wn0, call_wn); 00838 if (rtype < MTYPE_M) { 00839 wn2 = WN_Ldid (rtype, -1, Return_Val_Preg, ret_ty); 00840 call_wn = WN_CreateComma(OPR_COMMA, WN_rtype(wn2), MTYPE_V, wn0, wn2); 00841 } else 00842 call_wn = wn0; 00843 } 00844 00845 spill: 00846 if (rtype < MTYPE_M || (is_struct && !dest)) { 00847 wn1 = WN_CreateBlock(); 00848 if (rtype < MTYPE_M) { 00849 00850 //for assignments whirl2c casts lhs to a pointer with the rhs type 00851 //Until we fix that - generate the temp with the register size/type 00852 //rather than the lhs type. 00853 if(rtype != MTYPE_F4 && rtype != MTYPE_F8) { 00854 // ret_ty = ( _64_bit_target) ? 00855 // (MTYPE_is_unsigned(rtype) ? MTYPE_To_TY(MTYPE_U8) : MTYPE_To_TY(MTYPE_I8)) : 00856 // (MTYPE_is_unsigned(rtype) ? MTYPE_To_TY(MTYPE_U4) :MTYPE_To_TY(MTYPE_I4) ) 00857 ; 00858 } 00859 ret_st = Gen_Temp_Symbol(ret_ty, (char*) ".Tspilload"); 00860 WN_INSERT_BlockLast (wn1, WN_Stid (TY_mtype(ret_ty), 0, ret_st, 00861 ret_ty, call_wn)); 00862 rtype = Widen_Mtype(TY_mtype(ret_ty)); 00863 if (MTYPE_is_integral(desc)) { 00864 if (MTYPE_signed(rtype) != MTYPE_signed(desc)) { 00865 if (MTYPE_size_min(rtype) > MTYPE_size_min(desc)) 00866 rtype = Mtype_TransferSign(desc, rtype); 00867 else desc = Mtype_TransferSign(rtype, desc); 00868 } 00869 } 00870 } else WN_INSERT_BlockLast (wn1, call_wn); 00871 00872 00873 if(TY_kind(ret_ty) == KIND_SCALAR && rtype != MTYPE_F4 && rtype != MTYPE_F8 ) { 00874 if(consistency == RELAXED_CONSISTENCY && rtype == MTYPE_M && 00875 (TY_mtype(ret_ty) == MTYPE_F4 || TY_mtype(ret_ty) == MTYPE_F8)) 00876 rtype = desc = TY_mtype(ret_ty); 00877 else 00878 rtype // = desc 00879 = // TY_mtype(ret_ty) 00880 ( _64_bit_target) ? 00881 (MTYPE_is_unsigned(rtype) ? MTYPE_U8 : MTYPE_I8) : 00882 (MTYPE_is_unsigned(rtype) ? MTYPE_U4 :MTYPE_I4 ) ; 00883 } else if (TY_kind(ret_ty) == KIND_SCALAR && (rtype == MTYPE_F4 || rtype == MTYPE_F8)) 00884 rtype = desc = TY_mtype(ret_ty); 00885 00886 call_wn = WN_CreateComma (OPR_COMMA, rtype, MTYPE_V, wn1, 00887 WN_CreateLdid(OPR_LDID, rtype, desc, ST_ofst(ret_st), 00888 ret_st, ret_ty, 0) ); 00889 00890 } 00891 00892 // fprintf(stderr,"Shared Load OUT"); 00893 // fdump_tree(stderr, call_wn); 00894 00895 return call_wn; 00896 } 00897 00898 00899 00900 00901 // assumes lowering already called on the children of the ADD/SUB 00902 // i.e. base returns a shared_ptr_t 00903 WN* 00904 WN_Create_Shared_Ptr_Arithmetic( WN *base, WN *disp, OPERATOR opr, 00905 int esize, int bsize, int phaseless) 00906 { 00907 // fprintf(stderr,"Shared Ptr Arith IN : "); 00908 // fdump_tree(stderr, base); 00909 // fprintf(stderr,"PTR ARITH DISP : "); 00910 // fdump_tree(stderr, disp); 00911 00912 WN *call_wn; 00913 TY_IDX actual_shared_ptr_idx = (bsize <= 1) ? pshared_ptr_idx : shared_ptr_idx; 00914 TYPE_ID rtype = TY_mtype(actual_shared_ptr_idx); 00915 00916 call_wn = WN_Create (OPR_INTRINSIC_CALL, 00917 (rtype == MTYPE_M) ? MTYPE_M : Shared_Load_Extend_Mtyp(rtype), 00918 MTYPE_V, (bsize <= 1) ? 3 : 4 ); 00919 WN_intrinsic(call_wn) = WN_Operator_To_Intrinsic (opr, bsize); 00920 00921 if(WN_operator(base) == OPR_TAS) 00922 base = WN_kid0(base); 00923 00924 WN_kid0(call_wn) = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), base, 00925 actual_shared_ptr_idx, WN_PARM_BY_VALUE); 00926 TY_IDX tidx = WN_ty(base); 00927 WN_kid1(call_wn) = WN_CreateParm(Integer_type, 00928 WN_Intconst(Integer_type, esize), 00929 MTYPE_To_TY(Integer_type), 00930 WN_PARM_BY_VALUE); 00931 00932 WN_kid2(call_wn) = WN_CreateParm(WN_rtype(disp), disp, 00933 MTYPE_To_TY(WN_rtype(disp)), 00934 WN_PARM_BY_VALUE); 00935 if (bsize > 1) 00936 WN_kid3(call_wn) = WN_CreateParm(Integer_type, 00937 WN_Intconst(Integer_type, bsize), 00938 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 00939 00940 WN *wn0 = WN_CreateBlock(); 00941 WN_INSERT_BlockLast (wn0, call_wn); 00942 WN *wn1 = WN_Ldid(rtype, -1, Return_Val_Preg, actual_shared_ptr_idx); 00943 WN *wn2; 00944 00945 ST *ret_st; 00946 ret_st = Gen_Temp_Symbol(actual_shared_ptr_idx, (char*) ".Mreturn."); 00947 wn1 = WN_Stid (TY_mtype(actual_shared_ptr_idx), 0, ret_st, actual_shared_ptr_idx, wn1); 00948 WN_INSERT_BlockLast (wn0, wn1); 00949 wn2 = WN_CreateLdid(OPR_LDID, rtype, rtype, ST_ofst(ret_st), 00950 ret_st, actual_shared_ptr_idx, 0); 00951 00952 00953 wn1 = WN_CreateComma (OPR_COMMA, WN_rtype (wn2), MTYPE_V, wn0, wn2); 00954 // fprintf(stderr,"Shared Ptr Arith OUT : "); 00955 // fdump_tree(stderr, wn1); 00956 return wn1; 00957 } 00958 00959 00960 WN* 00961 WN_Convert_Shared_To_Local ( WN *ptr, TY_IDX ty, ST* st) 00962 { 00963 int st0 = 0; 00964 00965 00966 // A TAS here was artificially generated in the front-end only to 00967 // pass the type info. 00968 if(WN_operator(ptr) == OPR_TAS) 00969 ptr = WN_kid0(ptr); 00970 00971 TY_IDX sptr_idx = WN_ty(ptr); 00972 00973 if (!sptr_idx) { 00974 Is_True(WN_operator(ptr) == OPR_COMMA, 00975 ("Can't determine the the implementation type of shared ptr in cast to local","")); 00976 sptr_idx = TY_To_Sptr_Idx(WN_ty(WN_kid1(ptr))); 00977 } 00978 00979 if(!st /*&& TY_mtype(sptr_idx) != MTYPE_M */) { 00980 // cast to local in the middle of an expression 00981 if(ty == 0) 00982 ty = MTYPE_To_TY(Pointer_Mtype); 00983 st = Gen_Temp_Symbol(ty, (char*) ".Mcvtptr."); 00984 st0 = 1; 00985 } 00986 00987 00988 WN *call_wn = WN_Create (OPR_INTRINSIC_CALL, Pointer_Mtype, MTYPE_V, 1); 00989 if (sptr_idx == shared_ptr_idx) 00990 WN_intrinsic (call_wn) = INTRN_SCVTADDR; 00991 else 00992 WN_intrinsic (call_wn) = INTRN_P_TO_L; 00993 00994 00995 WN_kid0 (call_wn) = WN_CreateParm(TY_mtype(sptr_idx), ptr, sptr_idx, WN_PARM_BY_VALUE); 00996 00997 WN *wn0 = WN_CreateBlock(); 00998 WN_INSERT_BlockLast (wn0, call_wn); 00999 WN *wn1 = WN_Ldid(Pointer_Mtype, -1, Return_Val_Preg, ty); 01000 call_wn = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, wn0, wn1); 01001 if(st0) { 01002 call_wn = WN_CreateStid(OPR_STID, MTYPE_V, Pointer_Mtype, 0, st, ty, call_wn, 0); 01003 wn0 = WN_CreateBlock(); 01004 WN_INSERT_BlockLast(wn0, call_wn); 01005 wn1 = WN_Ldid(TY_mtype(ty), 0, st, ty, 0); 01006 call_wn = WN_CreateComma(OPR_COMMA, TY_mtype(ty), MTYPE_V, wn0, wn1); 01007 } 01008 01009 // fprintf(stderr, "SHARED_TO_LOCAL \n"); 01010 // fdump_tree(stderr, call_wn); 01011 return call_wn; 01012 } 01013 01014 01015 WN * 01016 WN_Create_PtrEq_Test(OPERATOR op, WN *awn0, WN *awn1, TY_IDX idx0, TY_IDX idx1) 01017 { 01018 INTRINSIC iop = INTRN_EQ_P_P; 01019 BOOL negate = FALSE; 01020 UINT args = 2; 01021 01022 01023 WN *arg0 = awn0; 01024 WN *arg1 = awn1; 01025 TY_IDX tmp; 01026 01027 if (Type_Is_Shared_Ptr(idx0)) 01028 idx0 = TY_To_Sptr_Idx (idx0); 01029 else { 01030 if(WN_operator(arg0) == OPR_LDID) 01031 idx0 = TY_To_Sptr_Idx(WN_ty(arg0)); 01032 } 01033 01034 if (Type_Is_Shared_Ptr(idx1)) 01035 idx1 = TY_To_Sptr_Idx (idx1); 01036 else { 01037 if(WN_operator(arg1) == OPR_LDID) 01038 idx1 = TY_To_Sptr_Idx(WN_ty(arg1)); 01039 } 01040 01041 iop = WN_Operator_To_Intrinsic(OPR_EQ, idx0, idx1); 01042 01043 if(WN_operator(awn0) == OPR_INTCONST) { 01044 args = 1; 01045 arg0 = awn1; 01046 } else if (WN_operator(awn1) == OPR_INTCONST) { 01047 args = 1; 01048 arg0 = awn0; 01049 } else if(idx0 == pshared_ptr_idx) { 01050 arg0 = awn1; 01051 arg1 = awn0; 01052 tmp = idx0; 01053 idx0 = idx1; 01054 idx1 = tmp; 01055 01056 } 01057 01058 switch (op) { 01059 case OPR_EQ: 01060 break; 01061 case OPR_NE: 01062 negate = TRUE; 01063 break; 01064 default: 01065 Is_True(0,("","")); 01066 } 01067 01068 WN *call_wn = WN_Create(OPR_INTRINSIC_CALL, MTYPE_I4, MTYPE_V, args); 01069 WN_intrinsic(call_wn) = iop; 01070 01071 WN_kid0(call_wn) = WN_CreateParm(TY_mtype(idx0), arg0, idx0, WN_PARM_BY_VALUE); 01072 01073 if(args > 1) { 01074 WN_kid1(call_wn) = WN_CreateParm(TY_mtype(idx1), arg1, idx1, WN_PARM_BY_VALUE); 01075 } 01076 01077 WN *wn0 = WN_CreateBlock(); 01078 WN_INSERT_BlockLast (wn0, call_wn); 01079 WN *wn1 = WN_Ldid(MTYPE_I4, -1, Return_Val_Preg, MTYPE_To_TY(MTYPE_I4)); 01080 01081 wn1 = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, wn0, wn1); 01082 if (negate) 01083 wn1 = WN_LNOT(wn1); 01084 01085 ST *st = Gen_Temp_Symbol(MTYPE_To_TY(MTYPE_I4), (char*) ".Mptreq."); 01086 idx0 = MTYPE_To_TY(MTYPE_I4); 01087 wn1 = WN_CreateStid(OPR_STID, MTYPE_V, MTYPE_I4, 0, st, idx0, wn1, 0); 01088 wn0 = WN_CreateBlock(); 01089 WN_INSERT_BlockLast(wn0, wn1); 01090 wn1 = WN_Ldid(MTYPE_I4, 0, st, idx0, 0); 01091 wn1 = WN_CreateComma(OPR_COMMA, MTYPE_I4, MTYPE_V, wn0, wn1); 01092 01093 return wn1; 01094 } 01095 01096 01097 WN* 01098 WN_Create_StoP_Cvt(WN *init_wn, INTRINSIC iop) 01099 { 01100 01101 TY_IDX ret_ty; 01102 TY_IDX arg_ty; 01103 01104 switch(iop) { 01105 case INTRN_S_RESET: 01106 ret_ty = arg_ty = shared_ptr_idx; 01107 break; 01108 case INTRN_S_TO_P: 01109 ret_ty = pshared_ptr_idx; 01110 arg_ty = shared_ptr_idx; 01111 break; 01112 case INTRN_P_TO_S: 01113 ret_ty = shared_ptr_idx; 01114 arg_ty = pshared_ptr_idx; 01115 break; 01116 case INTRINSIC_LAST: 01117 return init_wn; 01118 default: 01119 Is_True(0, ("Bad intrinsic value in PtoS_Cvt","")); 01120 } 01121 01122 WN *call_wn = WN_Create(OPR_INTRINSIC_CALL, TY_mtype(ret_ty), 01123 MTYPE_V, 1); 01124 WN_intrinsic(call_wn) = iop; 01125 WN_kid0(call_wn) = 01126 WN_CreateParm(TY_mtype(arg_ty), init_wn, arg_ty, WN_PARM_BY_VALUE); 01127 01128 TY_IDX ty_idx1 = shared_ptr_idx; 01129 TY_IDX component_ty_idx = shared_ptr_idx; 01130 TY_IDX nop_ty_idx = shared_ptr_idx; 01131 01132 WN *wn0 = WN_CreateBlock(); 01133 WN_INSERT_BlockLast (wn0, call_wn); 01134 WN *wn1 = WN_Ldid(TY_mtype(ret_ty), -1, Return_Val_Preg, ret_ty); 01135 01136 ST *ret_st = Gen_Temp_Symbol(ret_ty, (char*) ".Mstopcvt."); 01137 wn1 = WN_Stid (TY_mtype(ret_ty), 0, ret_st, ret_ty, wn1); 01138 WN_INSERT_BlockLast (wn0, wn1); 01139 wn1 = WN_CreateLdid(OPR_LDID, TY_mtype(ret_ty), TY_mtype(ret_ty), 0, 01140 ret_st, ret_ty, 0); 01141 01142 wn1 = WN_CreateComma (OPR_COMMA, WN_rtype (wn1), MTYPE_V, wn0, wn1); 01143 01144 return wn1; 01145 01146 } 01147 01148 01149 01150 WN * 01151 Spill_Shared_Load( WN *ld) 01152 { 01153 // fdump_tree(stderr, ld); 01154 Is_True(WN_operator(ld) == OPR_COMMA || WN_operator(ld) == OPR_LDID, ("","")); 01155 WN *block = WN_CreateBlock(); 01156 01157 TY_IDX idx = WN_ty(WN_operator(ld) == OPR_COMMA ? WN_kid1(ld) : ld); 01158 ST* ret_st = Gen_Temp_Symbol(idx, 01159 Index_To_Str(Save_Str2((char*)".Mreturn.",(char*)".Mreturn."))); 01160 WN_INSERT_BlockLast (block, WN_Stid (TY_mtype(idx), 0, ret_st, idx, ld)); 01161 return WN_CreateComma (OPR_COMMA, Widen_Mtype(TY_mtype(idx)),MTYPE_V, block, 01162 WN_Ldid(TY_mtype(idx), 0, ret_st, idx)); 01163 } 01164 01165 01166 void LowerUPC_Init_Consistency() 01167 { 01168 static int first = 1; 01169 01170 if (first) { 01171 MEM_POOL_Initialize(&consistency_pool, "Memory consistency pool", FALSE); 01172 MEM_POOL_Push(&consistency_pool); 01173 consistency_map = WN_MAP_Create(&consistency_pool); 01174 first = 0; 01175 } 01176 } 01177 01178 01179 WN * 01180 WN_Create_Shared_Ptr_Diff( WN *op0, WN *op1, TY_IDX t1, TY_IDX t2) 01181 { 01182 01183 WN *call_wn; 01184 01185 TYPE_ID rtype = MTYPE_I4; 01186 TY_IDX ret_ty = MTYPE_To_TY(rtype); 01187 int esize = Get_Type_Inner_Size(t1); 01188 int bsize = Get_Type_Block_Size(t1); 01189 //t1, t2 are both guaranteed to be local pointer to shared data 01190 t1 = TY_pointed(t1); 01191 t2 = TY_pointed(t2); 01192 01193 if (!TY_is_pshared(t1)) { 01194 call_wn = WN_Create (OPR_INTRINSIC_CALL, rtype, MTYPE_V, 4 ); 01195 WN_intrinsic(call_wn) = INTRN_SUB_S; 01196 01197 WN_kid0(call_wn) = WN_CreateParm(TY_mtype(shared_ptr_idx), op0, 01198 shared_ptr_idx, WN_PARM_BY_VALUE); 01199 if (TY_is_pshared(t2)) { 01200 op1 = WN_Create_StoP_Cvt(op1, INTRN_P_TO_S); 01201 } 01202 WN_kid1(call_wn) = WN_CreateParm(TY_mtype(shared_ptr_idx), op1, 01203 shared_ptr_idx, WN_PARM_BY_VALUE); 01204 WN_kid2(call_wn) = WN_CreateParm(Integer_type, 01205 WN_Intconst(Integer_type, esize), 01206 MTYPE_To_TY(Integer_type), 01207 WN_PARM_BY_VALUE); 01208 WN_kid3(call_wn) = WN_CreateParm(Integer_type, 01209 WN_Intconst(Integer_type, bsize ? bsize: 1), 01210 MTYPE_To_TY(Integer_type), WN_PARM_BY_VALUE); 01211 } else { 01212 call_wn = WN_Create (OPR_INTRINSIC_CALL, rtype, MTYPE_V, 3); 01213 if (TY_block_size(t1) == 1) { 01214 WN_intrinsic(call_wn) = INTRN_SUB_P1; 01215 } else { 01216 WN_intrinsic(call_wn) = INTRN_SUB_PI; 01217 } 01218 WN_kid0 (call_wn) = WN_CreateParm(TY_mtype(pshared_ptr_idx), op0, 01219 pshared_ptr_idx, WN_PARM_BY_VALUE); 01220 01221 if (!TY_is_pshared(t2)) { 01222 op1 = WN_Create_StoP_Cvt(op1, INTRN_S_TO_P); 01223 } 01224 WN_kid1(call_wn) = WN_CreateParm(TY_mtype(pshared_ptr_idx), op1, 01225 pshared_ptr_idx, WN_PARM_BY_VALUE); 01226 WN_kid2(call_wn) = WN_CreateParm(Integer_type, 01227 WN_Intconst(Integer_type, esize), 01228 MTYPE_To_TY(Integer_type), 01229 WN_PARM_BY_VALUE); 01230 } 01231 01232 WN *wn0 = WN_CreateBlock(); 01233 WN_INSERT_BlockLast (wn0, call_wn); 01234 WN *wn1 = WN_Ldid(rtype, -1, Return_Val_Preg, ret_ty); 01235 WN *wn2; 01236 01237 ST *ret_st; 01238 ret_st = Gen_Temp_Symbol(ret_ty, (char*) ".Mreturn."); 01239 wn1 = WN_Stid (rtype, 0, ret_st, ret_ty, wn1); 01240 WN_INSERT_BlockLast (wn0, wn1); 01241 wn2 = WN_CreateLdid(OPR_LDID, rtype, rtype, ST_ofst(ret_st), 01242 ret_st, ret_ty, 0); 01243 01244 wn1 = WN_CreateComma (OPR_COMMA, rtype, MTYPE_V, wn0, wn2); 01245 return wn1; 01246 } 01247 01248 01249 01250 WN* 01251 WN_SetNull_Sptr(WN *st) { 01252 01253 WN *call_wn; 01254 TY_IDX actual_shared_ptr_idx; 01255 WN *arg; 01256 INTRINSIC iop; 01257 01258 call_wn = WN_Create (OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V, 1); 01259 actual_shared_ptr_idx = TY_To_Sptr_Idx(WN_ty(st)); 01260 switch (WN_operator(st)) { 01261 case OPR_STID: 01262 01263 WN_kid0(call_wn) = WN_CreateParm(Pointer_Mtype, WN_Lda(Pointer_Mtype, 0, WN_st(st), 0), 01264 MTYPE_To_TY(Pointer_Mtype), WN_PARM_BY_VALUE); 01265 // WN_kid0(call_wn) = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), 01266 // WN_CreateLdid(OPR_LDID, 01267 // TY_mtype(actual_shared_ptr_idx), 01268 // TY_mtype(actual_shared_ptr_idx), 01269 // 0 , ST_st_idx(WN_st(st)), 01270 // actual_shared_ptr_idx, 0), 01271 // actual_shared_ptr_idx, WN_PARM_BY_VALUE); 01272 WN_intrinsic(call_wn) = (actual_shared_ptr_idx == shared_ptr_idx) ? 01273 INTRN_SETNULL_S : INTRN_SETNULL_P; 01274 break; 01275 case OPR_ISTORE: 01276 case OPR_MSTORE: 01277 if(actual_shared_ptr_idx == pshared_ptr_idx) { 01278 //need to convert to shared first 01279 WN_kid1(st) = WN_Create_StoP_Cvt(WN_kid1(st), INTRN_P_TO_S); 01280 actual_shared_ptr_idx = shared_ptr_idx; 01281 } 01282 01283 WN_kid0(call_wn) = WN_CreateParm(TY_mtype(actual_shared_ptr_idx), WN_kid1(st), 01284 actual_shared_ptr_idx, 01285 WN_PARM_BY_VALUE); 01286 WN_intrinsic(call_wn) = (TY_To_Sptr_Idx(TY_pointed(WN_ty(st))) == shared_ptr_idx) ? 01287 INTRN_SETNULL_S_R : INTRN_SETNULL_P_R; 01288 break; 01289 default: 01290 Is_True(0,("","")); 01291 } 01292 01293 return call_wn; 01294 } 01295 01296 01297 01298 WN* 01299 Strip_TAS(WN *wn) 01300 { 01301 while(WN_operator(wn) == OPR_TAS) 01302 wn = WN_kid0(wn); 01303 return wn; 01304 } 01305 01306 WN *Combine_Offset_Terms(SPTR_OFFSET_TERM_STACK &stack) 01307 { 01308 if(stack.empty()) 01309 return 0; 01310 WN *wn0 = stack.top(); 01311 stack.pop(); 01312 if(stack.empty()) 01313 return wn0; 01314 WN *wn1 = stack.top(); 01315 stack.pop(); 01316 01317 wn0 = WN_Binary (OPR_ADD, MTYPE_I4, wn0, wn1); 01318 01319 while(!stack.empty()) { 01320 wn1 = stack.top(); 01321 stack.pop(); 01322 wn0 = WN_Binary (OPR_ADD, MTYPE_I4, wn0, wn1); 01323 } 01324 01325 return wn0; 01326 01327 } 01328 01329 01330 TY_IDX Get_Type_From_ArrayOp(WN *array_wn) 01331 { 01332 01333 WN *base = array_wn; 01334 TY_IDX result; 01335 01336 if (WN_operator(array_wn) == OPR_ARRAY) { 01337 base = WN_array_base(array_wn); 01338 while(WN_operator(base) == OPR_ARRAY) { 01339 base = WN_array_base(base); 01340 } 01341 } 01342 01343 if (WN_operator(base) == OPR_LDA) 01344 result = TY_pointed(WN_ty(base)); 01345 else 01346 result = WN_ty(base); 01347 01348 return result; 01349 }