00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "common_include.h"
00054 #include "wn_util.h"
00055 #include "intrn_info.h"
00056 #include "wutil.h"
00057 #include "unparse_target.h"
00058
00059
00060
00061
00062 static const MTYPE WN_Cvtl_Mtype[2][9] =
00063 {
00064 {MTYPE_UNKNOWN,
00065 MTYPE_U1,
00066 MTYPE_U2,
00067 MTYPE_UNKNOWN,
00068 MTYPE_U4,
00069 MTYPE_UNKNOWN,
00070 MTYPE_UNKNOWN,
00071 MTYPE_UNKNOWN,
00072 MTYPE_U8},
00073
00074 {MTYPE_UNKNOWN,
00075 MTYPE_I1,
00076 MTYPE_I2,
00077 MTYPE_UNKNOWN,
00078 MTYPE_I4,
00079 MTYPE_UNKNOWN,
00080 MTYPE_UNKNOWN,
00081 MTYPE_UNKNOWN,
00082 MTYPE_I8}
00083 };
00084
00085 static TY_IDX
00086 WN_Cvtl_Ty(const WN *wn)
00087 {
00088
00089
00090
00091 const INT cvtl_bytes = WN_cvtl_bits(wn)>>3;
00092 const MTYPE dest_mtype = WN_opc_rtype(wn);
00093 const BOOL is_signed = MTYPE_signed(dest_mtype);
00094 const MTYPE cvtl_mtype = WN_Cvtl_Mtype[is_signed? 1 : 0][cvtl_bytes];
00095
00096 return Stab_Mtype_To_Ty(cvtl_mtype);
00097 }
00098
00099 TY_IDX Get_Field_Type(TY_IDX base, int field_id) {
00100
00101 Is_True(TY_Is_Structured(base), ("CALLING GET_FIELD_TYPE with a non struct type"));
00102
00103 UINT cur_fld_id = 0;
00104 FLD_HANDLE fh = FLD_get_to_field(base, field_id, cur_fld_id);
00105 return FLD_type(fh);
00106 }
00107
00108
00109
00110
00111
00112 static TY_IDX
00113 WN_get_tld_type(const WN* wn) {
00114
00115
00116 WN* kid = WN_kid0(WN_kid0(wn));
00117 TY_IDX result_ty = WN_Tree_Type(kid);
00118 switch (TY_kind(result_ty)) {
00119 case KIND_ARRAY: {
00120 TY_IDX new_ty;
00121 int dim = 1;
00122 for (new_ty = TY_etype(result_ty); TY_kind(new_ty) == KIND_ARRAY; new_ty = TY_etype(new_ty), dim++);
00123 for (;dim > 0; new_ty = Make_Pointer_Type(new_ty), dim--);
00124 return new_ty;
00125 }
00126 case KIND_STRUCT:
00127 if (WN_field_id(kid) != 0) {
00128 return Make_Pointer_Type(Get_Field_Type(result_ty, WN_field_id(kid)));
00129 }
00130 return Make_Pointer_Type(result_ty);
00131 case KIND_POINTER: {
00132
00133 TY_IDX pointed = TY_pointed(result_ty);
00134 if (TY_is_shared(pointed)) {
00135 if (TY_kind(pointed) != KIND_VOID &&
00136 Get_Type_Block_Size(pointed) <= 1) {
00137 return Make_Pointer_Type(Make_Pointer_Type(pshared_ptr_idx));
00138 } else {
00139 return Make_Pointer_Type(Make_Pointer_Type(shared_ptr_idx));
00140 }
00141 }
00142
00143 }
00144 default:
00145 return Make_Pointer_Type(result_ty);
00146 }
00147 }
00148
00149 UINT
00150 WN_num_var_refs(WN *wn, const ST *st, STAB_OFFSET st_ofst)
00151 {
00152
00153
00154
00155 UINT counter = 0;
00156 WN_ITER *wn_iter;
00157 const WN *subtree;
00158
00159 for (wn_iter = WN_WALK_TreeIter(wn);
00160 wn_iter != NULL;
00161 wn_iter = WN_WALK_TreeNext(wn_iter))
00162 {
00163 subtree = WN_ITER_wn(wn_iter);
00164 if (subtree != NULL)
00165 switch (WN_opc_operator(subtree))
00166 {
00167 case OPR_LDID:
00168 case OPR_STID:
00169 case OPR_LDA:
00170 if (WN_st(subtree) == st && WN_offset(subtree) == st_ofst)
00171 counter += 1;
00172 break;
00173
00174 default:
00175 break;
00176 }
00177 }
00178 return counter;
00179 }
00180
00181
00182 const char *
00183 WN_intrinsic_name(INTRINSIC intr_opc)
00184 {
00185 return W2X_Unparse_Target->Intrinsic_Name(intr_opc);
00186 }
00187
00188 TY_IDX
00189 WN_intrinsic_return_ty(OPCODE wn_opc, INTRINSIC intr_opc, const WN *call)
00190 {
00191 TY_IDX ret_ty;
00192
00193 Is_True(INTRINSIC_FIRST<=intr_opc && intr_opc<=INTRINSIC_LAST,
00194 ("Intrinsic Opcode (%d) out of range", intr_opc));
00195 switch (INTRN_return_kind(intr_opc))
00196 {
00197 case IRETURN_UNKNOWN:
00198
00199 ret_ty = Stab_Mtype_To_Ty(OPCODE_rtype(wn_opc));
00200 break;
00201 case IRETURN_V:
00202 ret_ty = Stab_Mtype_To_Ty(MTYPE_V);
00203 break;
00204 case IRETURN_I1:
00205 ret_ty = Stab_Mtype_To_Ty(MTYPE_I1);
00206 break;
00207 case IRETURN_I2:
00208 ret_ty = Stab_Mtype_To_Ty(MTYPE_I2);
00209 break;
00210 case IRETURN_I4:
00211 ret_ty = Stab_Mtype_To_Ty(MTYPE_I4);
00212 break;
00213 case IRETURN_I8:
00214 ret_ty = Stab_Mtype_To_Ty(MTYPE_I8);
00215 break;
00216 case IRETURN_U1:
00217 ret_ty = Stab_Mtype_To_Ty(MTYPE_U1);
00218 break;
00219 case IRETURN_U2:
00220 ret_ty = Stab_Mtype_To_Ty(MTYPE_U2);
00221 break;
00222 case IRETURN_U4:
00223 ret_ty = Stab_Mtype_To_Ty(MTYPE_U4);
00224 break;
00225 case IRETURN_U8:
00226 ret_ty = Stab_Mtype_To_Ty(MTYPE_U8);
00227 break;
00228 case IRETURN_F4:
00229 ret_ty = Stab_Mtype_To_Ty(MTYPE_F4);
00230 break;
00231 case IRETURN_F8:
00232 ret_ty = Stab_Mtype_To_Ty(MTYPE_F8);
00233 break;
00234 case IRETURN_FQ:
00235 ret_ty = Stab_Mtype_To_Ty(MTYPE_FQ);
00236 break;
00237 case IRETURN_C4:
00238 ret_ty = Stab_Mtype_To_Ty(MTYPE_C4);
00239 break;
00240 case IRETURN_C8:
00241 ret_ty = Stab_Mtype_To_Ty(MTYPE_C8);
00242 break;
00243 case IRETURN_CQ:
00244 ret_ty = Stab_Mtype_To_Ty(MTYPE_CQ);
00245 break;
00246 case IRETURN_PV:
00247 ret_ty = Stab_Pointer_To(Stab_Mtype_To_Ty(MTYPE_V));
00248 break;
00249 case IRETURN_PU1:
00250 ret_ty = Stab_Pointer_To(Stab_Mtype_To_Ty(MTYPE_U1));
00251 break;
00252 case IRETURN_DA1:
00253 ret_ty = WN_Tree_Type(WN_kid0(call));
00254 break;
00255 case IRETURN_M:
00256 ret_ty = Stab_Mtype_To_Ty(MTYPE_M);
00257 break;
00258
00259 case IRETURN_PC:
00260 ret_ty = Stab_Pointer_To(Stab_Mtype_To_Ty(MTYPE_V));
00261 break;
00262 case IRETURN_SZT:
00263 ret_ty = Stab_Mtype_To_Ty(MTYPE_I4);
00264 break;
00265
00266 case IRETURN_F10:
00267 ret_ty = Stab_Mtype_To_Ty(MTYPE_F10);
00268 break;
00269 default:
00270 Is_True(FALSE,
00271 ("Unexpected INTRN_RETKIND in WN_intrinsic_return_ty()"));
00272 ret_ty = Stab_Mtype_To_Ty(MTYPE_V);
00273 break;
00274 }
00275
00276 return ret_ty;
00277 }
00278
00279
00280 BOOL
00281 WN_intrinsic_return_to_param(TY_IDX return_ty)
00282 {
00283
00284
00285
00286
00287 return (TY_mtype(return_ty) == MTYPE_CQ);
00288
00289 }
00290
00291
00292 WN *
00293 WN_Get_PtrAdd_Intconst(WN *wn0,
00294 WN *wn1,
00295 TY_IDX pointed_ty)
00296 {
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 WN *intconst = NULL;
00311
00312
00313 if (!TY_Is_Pointer(WN_Tree_Type(wn0)))
00314 intconst = wn0;
00315 else if (!TY_Is_Pointer(WN_Tree_Type(wn1)))
00316 intconst = wn1;
00317
00318
00319 if (intconst != NULL && TY_size(pointed_ty) > 1)
00320 {
00321
00322 if (WN_opc_operator(intconst) == OPR_MPY)
00323 {
00324 if (WN_opc_operator(WN_kid0(intconst)) == OPR_INTCONST)
00325 intconst = WN_kid0(intconst);
00326 else if (WN_opc_operator(WN_kid1(intconst)) == OPR_INTCONST)
00327 intconst = WN_kid1(intconst);
00328 else
00329 intconst = NULL;
00330 }
00331 else if (WN_opc_operator(intconst) != OPR_INTCONST)
00332 intconst = NULL;
00333 }
00334
00335
00336
00337
00338 if (TY_size(pointed_ty) == 0 ||
00339 (intconst != NULL &&
00340 WN_opc_operator(intconst) == OPR_INTCONST &&
00341 WN_const_val(intconst)%TY_size(pointed_ty) != 0LL))
00342 {
00343 intconst = NULL;
00344 }
00345 return intconst;
00346 }
00347
00348 TY_IDX
00349 WN_Tree_Type(const WN *wn)
00350 {
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 TY_IDX ty = Stab_Mtype_To_Ty(MTYPE_V);
00361
00362 if (wn == NULL)
00363 return ty;
00364
00365
00366 if (OPCODE_is_expression(WN_opcode(wn)))
00367 {
00368 switch (WN_opc_operator(wn))
00369 {
00370 case OPR_ILOAD:
00371 case OPR_ILOADX:
00372 ty = WN_ty(wn);
00373 if (TY_kind(ty) == KIND_STRUCT &&
00374 WN_field_id(wn) > 0) {
00375
00376 ty = TY_pointed(WN_load_addr_ty(wn));
00377 }
00378 break;
00379 case OPR_LDID:
00380 case OPR_LDA:
00381 ty = WN_ty(wn);
00382 break;
00383
00384 case OPR_MLOAD:
00385
00386 if (WN_opc_operator(WN_kid1(wn)) == OPR_INTCONST &&
00387 TY_Is_Structured(TY_pointed(WN_ty(wn))))
00388 {
00389
00390
00391 if (WN_field_id(wn) != 0) {
00392 ty = Get_Field_Type(TY_pointed(WN_ty(wn)), WN_field_id(wn));
00393 } else {
00394 ty = Stab_Get_Mload_Ty(TY_pointed(WN_ty(wn)),
00395 WN_load_offset(wn),
00396 WN_const_val(WN_kid1(wn)));
00397 }
00398 }
00399 else
00400 {
00401 ty = TY_pointed(WN_ty(wn));
00402 }
00403 break;
00404 case OPR_ARRSECTION:
00405 case OPR_ARRAY:
00406 case OPR_ARRAYEXP:
00407 case OPR_ARRAY_CONSTRUCT:
00408 case OPR_IMPLIED_DO:
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 ty = WN_Tree_Type(WN_kid0(wn));
00426 #if 0 //FMZ Aug 2005
00427 if (!TY_Is_Pointer(ty))
00428 {
00429
00430
00431
00432
00433 ty = Stab_Pointer_To(Stab_Array_Of(Stab_Mtype_To_Ty(MTYPE_U1),
00434 WN_element_size(wn)));
00435 }
00436 else if (!TY_ptr_as_array(Ty_Table[ty]) && TY_Is_Array(TY_pointed(ty)))
00437 {
00438 ty = Stab_Pointer_To(TY_AR_etype(TY_pointed(ty)));
00439 }
00440 #endif
00441 break;
00442
00443 case OPR_TAS:
00444 ty = WN_ty(wn);
00445 break;
00446
00447 case OPR_SELECT:
00448
00449
00450
00451 if (WN_opc_rtype(wn) == Pointer_Mtype)
00452 {
00453 ty = WN_Tree_Type(WN_kid0(wn));
00454 if (!TY_Is_Pointer(ty))
00455 {
00456 ty = WN_Tree_Type(WN_kid1(wn));
00457 if (!TY_Is_Pointer(ty))
00458 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00459 }
00460 }
00461 else
00462 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00463 break;
00464
00465 case OPR_CVTL:
00466 ty = WN_Cvtl_Ty(wn);
00467 break;
00468
00469 case OPR_PAREN:
00470 ty = WN_Tree_Type(WN_kid0(wn));
00471 break;
00472
00473 case OPR_ADD:
00474
00475
00476
00477
00478
00479 if (WN_opc_rtype(wn) == Pointer_Mtype)
00480 {
00481 ty = WN_Tree_Type(WN_kid0(wn));
00482 if (!TY_Is_Pointer(ty))
00483 {
00484 ty = WN_Tree_Type(WN_kid1(wn));
00485 if (!TY_Is_Pointer(ty))
00486 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00487 }
00488
00489
00490 if (W2X_Unparse_Target->Reduce_Const_Ptr_Exprs() &&
00491 TY_Is_Pointer(ty) &&
00492 WN_Get_PtrAdd_Intconst(WN_kid0(wn),
00493 WN_kid1(wn),
00494 TY_pointed(ty)) == NULL)
00495 {
00496 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00497 }
00498 }
00499 else
00500 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00501 break;
00502
00503 case OPR_INTRINSIC_OP:
00504
00505 if (WN_intrinsic(wn) == INTRN_TLD_ADDR) {
00506
00507 ty = WN_get_tld_type(wn);
00508 break;
00509 }
00510
00511 if (INTR_is_adrtmp(WN_intrinsic(wn)))
00512 {
00513 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL ||
00514 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL)
00515 {
00516 ty = WN_Tree_Type(WN_kid0(WN_kid0(wn)));
00517 }
00518 else
00519 {
00520 ty = Stab_Pointer_To(WN_Tree_Type(WN_kid0(wn)));
00521 }
00522 }
00523 else if (INTR_is_valtmp(WN_intrinsic(wn)))
00524 {
00525 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL ||
00526 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL)
00527 {
00528 ty = TY_pointed(WN_Tree_Type(WN_kid0(WN_kid0(wn))));
00529 }
00530 else
00531 {
00532 ty = WN_Tree_Type(WN_kid0(wn));
00533 }
00534 }
00535 else
00536 {
00537 ty = WN_intrinsic_return_ty(WN_opcode(wn),
00538 (INTRINSIC)WN_intrinsic(wn), wn);
00539 }
00540 break;
00541
00542 case OPR_CVT:
00543 case OPR_NEG:
00544 case OPR_ABS:
00545 case OPR_SQRT:
00546 case OPR_REALPART:
00547 case OPR_IMAGPART:
00548 case OPR_RND:
00549 case OPR_TRUNC:
00550 case OPR_CEIL:
00551 case OPR_FLOOR:
00552 case OPR_BNOT:
00553 case OPR_LNOT:
00554 case OPR_SUB:
00555 case OPR_MPY:
00556 case OPR_DIV:
00557 case OPR_MOD:
00558 case OPR_REM:
00559 case OPR_MAX:
00560 case OPR_MIN:
00561 case OPR_BAND:
00562 case OPR_BIOR:
00563 case OPR_BXOR:
00564 case OPR_BNOR:
00565 case OPR_LAND:
00566 case OPR_LIOR:
00567 case OPR_CAND:
00568 case OPR_CIOR:
00569 case OPR_SHL:
00570 case OPR_ASHR:
00571 case OPR_LSHR:
00572 case OPR_COMPLEX:
00573 case OPR_RECIP:
00574 case OPR_RSQRT:
00575 case OPR_EQ:
00576 case OPR_NE:
00577 case OPR_GT:
00578 case OPR_GE:
00579 case OPR_LT:
00580 case OPR_LE:
00581 case OPR_CONST:
00582 case OPR_INTCONST:
00583 case OPR_DIVREM:
00584 case OPR_HIGHPART:
00585 case OPR_LOWPART:
00586 case OPR_HIGHMPY:
00587 ty = Stab_Mtype_To_Ty(WN_opc_rtype(wn));
00588 break;
00589
00590 case OPR_PARM:
00591 ty = WN_Tree_Type(WN_kid0(wn));
00592 break;
00593
00594 case OPR_COMMA:
00595 ty = WN_Tree_Type(WN_kid1(wn));
00596 break;
00597
00598 case OPR_RCOMMA:
00599 ty = WN_Tree_Type(WN_kid0(wn));
00600 break;
00601
00602 case OPR_ALLOCA:
00603 ty = WN_ty(wn);
00604 break;
00605
00606 case OPR_STRCTFLD:
00607 ty = WN_Tree_Type(WN_kid0(wn));
00608 break;
00609
00610 default:
00611
00612
00613
00614
00615
00616
00617
00618
00619 break;
00620 }
00621 }
00622 return ty;
00623 }
00624
00625
00626 void
00627 Remove_Skips(WN *ablock,
00628 W2CF_SKIP_ITEM *skip_info,
00629 INT *next_info_idx,
00630 INT max_info_idx,
00631 BOOL clist)
00632 {
00633
00634
00635 WN *parent;
00636 WN *stmt;
00637 WN_ITER *iter;
00638 W2CF_SKIP_ITEM *skip;
00639
00640 Is_True(WN_opcode(ablock) == OPC_BLOCK,
00641 ("expected OPC_BLOCK in Remove_Skips()"));
00642
00643 for (iter = WN_WALK_StmtIter(ablock);
00644 iter != NULL;
00645 iter = WN_WALK_StmtNext(iter))
00646 {
00647 parent = WN_ITER_wn(iter);
00648 if (WN_opcode(parent) == OPC_BLOCK)
00649 {
00650
00651
00652
00653 stmt = WN_first(parent);
00654 while (stmt != NULL)
00655 {
00656 if (WN_opc_operator(stmt) == OPR_PRAGMA &&
00657 (clist?
00658 WN_pragma(stmt) == WN_PRAGMA_CLIST_SKIP_BEGIN:
00659 WN_pragma(stmt) == WN_PRAGMA_FLIST_SKIP_BEGIN))
00660 {
00661 Is_True(*next_info_idx <= max_info_idx,
00662 ("exceeded max number of skip sequences"));
00663
00664
00665
00666 skip = &skip_info[*next_info_idx];
00667 *next_info_idx += 1;
00668
00669
00670
00671 skip->parent = parent;
00672 skip->first = stmt;
00673 while (clist?
00674 WN_pragma(stmt) != WN_PRAGMA_CLIST_SKIP_END:
00675 WN_pragma(stmt) != WN_PRAGMA_FLIST_SKIP_END)
00676 {
00677 stmt = WN_next(stmt);
00678 }
00679 skip->last = stmt;
00680
00681
00682
00683 if (WN_prev(skip->first) == NULL)
00684 WN_first(parent) = WN_next(skip->last);
00685 else
00686 WN_next(WN_prev(skip->first)) = WN_next(skip->last);
00687
00688 if (WN_last(parent) == skip->last)
00689 WN_last(parent) = WN_prev(skip->first);
00690 else
00691 WN_prev(WN_next(skip->last)) = WN_prev(skip->first);
00692 }
00693 stmt = WN_next(stmt);
00694 }
00695 }
00696 }
00697 }
00698
00699
00700 void
00701 Restore_Skips(const W2CF_SKIP_ITEM *skip_info,
00702 INT number_of_items,
00703 BOOL clist)
00704 {
00705 WN *parent, *prev, *next;
00706 const W2CF_SKIP_ITEM *skipped;
00707
00708 while (number_of_items > 0)
00709 {
00710 number_of_items--;
00711 skipped = &skip_info[number_of_items];
00712 parent = skipped->parent;
00713
00714
00715
00716
00717
00718
00719 prev = WN_prev(skipped->first);
00720 next = WN_next(skipped->last);
00721 if (prev == NULL && WN_prev(next) != NULL)
00722 prev = WN_first(parent);
00723 while (prev != NULL && WN_next(prev) != NULL && prev != WN_prev(next))
00724 prev = WN_next(prev);
00725
00726
00727
00728 if (prev == NULL)
00729 WN_first(parent) = skipped->first;
00730 else
00731 WN_next(prev) = skipped->first;
00732
00733 if (next == NULL)
00734 WN_last(parent) = skipped->last;
00735 else
00736 WN_prev(next) = skipped->last;
00737 }
00738 }