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
00057
00058 case MTYPE_F4:
00059
00060 case MTYPE_F8:
00061
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
00147 Is_True(0, ("Programming error.",""));
00148 return INTRINSIC_INVALID;
00149 }
00150
00151
00152
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
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
00295
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
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
00343 ;
00344
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
00358
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
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 , 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
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 {
00423 if (WN_operator(value) == OPR_LDID && WN_st_idx(value) != 0) {
00424 ST *tst;
00425
00426
00427 if(ST_class(WN_st(value)) == CLASS_PREG) {
00428
00429
00430
00431
00432
00433
00434
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
00457 (WN_operator(st) != OPR_STID && Type_Is_Shared_Ptr(TY_pointed(WN_ty(st)), TRUE)), ("",""));
00458
00459
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
00464
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
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
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
00556
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
00573
00574
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
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
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
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
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
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
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
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
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
00741
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
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
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
00851
00852
00853 if(rtype != MTYPE_F4 && rtype != MTYPE_F8) {
00854
00855
00856
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
00879 =
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
00893
00894
00895 return call_wn;
00896 }
00897
00898
00899
00900
00901
00902
00903 WN*
00904 WN_Create_Shared_Ptr_Arithmetic( WN *base, WN *disp, OPERATOR opr,
00905 int esize, int bsize, int phaseless)
00906 {
00907
00908
00909
00910
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
00955
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
00967
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 ) {
00980
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
01010
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
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
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
01266
01267
01268
01269
01270
01271
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
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 }