Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
upc_wn_util.cxx
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines