|
OpenADFortTk (basic)
|
00001 // -*-Mode: C++;-*- 00002 #include "Open64BasicTypes.h" 00003 00004 #include <sstream> 00005 #include "stab_attr.h" 00006 #include "wn_attr.h" 00007 #include "IFDiagnostics.h" 00008 #include "IntrinsicInfo.h" 00009 00010 static TY_IDX 00011 WN_get_tld_type(const WN* wn); 00012 00013 00020 #define INTRN_high_level_name INTRN_specific_name 00021 00022 00023 /*--------- Hidden utility to get type info about a cvtl node ---------* 00024 *---------------------------------------------------------------------*/ 00025 00026 static const MTYPE WN_Cvtl_Mtype[2/*is_signed*/][9/*byte-size*/] = 00027 {/* unsigned */ 00028 {MTYPE_UNKNOWN, /* 0 bytes */ 00029 MTYPE_U1, /* 1 byte */ 00030 MTYPE_U2, /* 2 bytes */ 00031 MTYPE_UNKNOWN, /* 3 bytes */ 00032 MTYPE_U4, /* 4 bytes */ 00033 MTYPE_UNKNOWN, /* 5 bytes */ 00034 MTYPE_UNKNOWN, /* 6 bytes */ 00035 MTYPE_UNKNOWN, /* 7 bytes */ 00036 MTYPE_U8}, /* 8 bytes */ 00037 /* signed */ 00038 {MTYPE_UNKNOWN, /* 0 bytes */ 00039 MTYPE_I1, /* 1 byte */ 00040 MTYPE_I2, /* 2 bytes */ 00041 MTYPE_UNKNOWN, /* 3 bytes */ 00042 MTYPE_I4, /* 4 bytes */ 00043 MTYPE_UNKNOWN, /* 5 bytes */ 00044 MTYPE_UNKNOWN, /* 6 bytes */ 00045 MTYPE_UNKNOWN, /* 7 bytes */ 00046 MTYPE_I8} /* 8 bytes */ 00047 }; /* WN_Cvtl_Mtype */ 00048 00049 static TY_IDX 00050 WN_Cvtl_Ty(const WN *wn) 00051 { 00052 /* The type of a CVTL node is the return type scaled down to the 00053 * given bitsize. 00054 */ 00055 const INT cvtl_bytes = WN_cvtl_bits(wn)>>3; 00056 const MTYPE dest_mtype = WN_rtype(wn); 00057 const BOOL is_signed = MTYPE_signed(dest_mtype); 00058 const MTYPE cvtl_mtype = WN_Cvtl_Mtype[is_signed? 1 : 0][cvtl_bytes]; 00059 00060 return Stab_Mtype_To_Ty(cvtl_mtype); 00061 } /* WN_Cvtl_Ty */ 00062 00063 00064 TY_IDX 00065 WN_Tree_Type(const WN* wn) 00066 { 00067 TY_IDX ty = MTYPE_To_TY(MTYPE_V); // default is void 00068 if (wn == NULL) 00069 return ty; 00070 00071 OPERATOR opr = WN_operator(wn); 00072 00073 if (OPERATOR_is_stmt(opr)) { 00074 // ------------------------------------------------------- 00075 // Statements 00076 // ------------------------------------------------------- 00077 if (OPERATOR_is_call(opr)) { 00078 // CALLs: statements and expressions (in VH WHIRL) 00079 ty = WN_Call_Return_Type(wn); 00080 } 00081 else if (OPERATOR_is_store(opr)) { 00082 // STOREs: return type of lhs referenced *object* 00083 ty = WN_GetRefObjType(wn); 00084 } 00085 } 00086 else if (OPERATOR_is_expression(opr)) { 00087 // ------------------------------------------------------- 00088 // Expressions 00089 // ------------------------------------------------------- 00090 switch (opr) { 00091 00092 // LOADs 00093 case OPR_LDA: 00094 case OPR_LDMA: 00095 case OPR_LDID: 00096 case OPR_LDBITS: 00097 case OPR_ILOAD: 00098 case OPR_ILOADX: // type of referenced object 00099 ty = WN_GetRefObjType(wn); 00100 break; 00101 00102 case OPR_MLOAD: // type of referenced object 00103 // There is not much we can do about this case 00104 if (WN_operator(WN_kid1(wn)) == OPR_INTCONST && 00105 TY_Is_Structured(TY_pointed(WN_ty(wn)))) { 00106 00107 /* WEI: for field accesses, get the type of the field */ 00108 if (WN_field_id(wn) != 0) { 00109 ty = Get_Field_Type(TY_pointed(WN_ty(wn)), WN_field_id(wn)); 00110 } else { 00111 ty = Stab_Get_Mload_Ty(TY_pointed(WN_ty(wn)), 00112 WN_load_offset(wn), 00113 WN_const_val(WN_kid1(wn))); 00114 } 00115 } else { 00116 ty = TY_pointed(WN_ty(wn)); 00117 } 00118 break; 00119 00120 // ARRAYs 00121 case OPR_ARRSECTION: 00122 case OPR_ARRAY: 00123 case OPR_ARRAYEXP: 00124 case OPR_ARRAY_CONSTRUCT: 00125 case OPR_IMPLIED_DO: 00126 /* Get the address type denoted by the base offset by the 00127 * given indexing expression. Note that we do handle 00128 * pointers as arrays when there is no ambiguity, and 00129 * we rely on the flag TY_ptr_as_array() to handle indexing 00130 * of an array of arrays. The following should access the 00131 * fifth element, each element consisting of 17 ints: 00132 * 00133 * int (*a)[17]; .... a[5] .... 00134 * 00135 * This will be represented as (OPR_ARRAY (OPR_LDID a) ...), 00136 * but, since the type of kid0 is ptr-to-arrayOfInts, we need 00137 * the flag TY_ptr_as_array or else the type of the ARRAY 00138 * node would be considered a ptr-to-ints (see also 00139 * WN2C_array()). 00140 */ 00141 ty = WN_Tree_Type(WN_kid0(wn)); 00142 if (!TY_Is_Pointer(ty)) { 00143 /* Create a pointer to be treated as an array when also used 00144 * as the base-type of this OPC_ARRAY. This must be handled 00145 * very carefully in WN2C_array(). 00146 */ 00147 ty = Stab_Pointer_To(Stab_Array_Of(MTYPE_To_TY(MTYPE_U1), 00148 WN_element_size(wn))); 00149 } 00150 else if (!TY_ptr_as_array(Ty_Table[ty]) && TY_Is_Array(TY_pointed(ty))) { 00151 ty = Stab_Pointer_To(TY_AR_etype(TY_pointed(ty))); 00152 } 00153 break; 00154 00155 case OPR_TAS: 00156 ty = WN_ty(wn); 00157 break; 00158 00159 case OPR_SELECT: 00160 // We make an attempt at retaining pointer types for ptr 00161 // arithmetics. 00162 if (WN_rtype(wn) == Pointer_Mtype) { 00163 ty = WN_Tree_Type(WN_kid0(wn)); 00164 if (!TY_Is_Pointer(ty)) { 00165 ty = WN_Tree_Type(WN_kid1(wn)); 00166 if (!TY_Is_Pointer(ty)) 00167 ty = MTYPE_To_TY(WN_rtype(wn)); 00168 } 00169 } else 00170 ty = MTYPE_To_TY(WN_rtype(wn)); 00171 break; 00172 00173 case OPR_CVTL: 00174 ty = WN_Cvtl_Ty(wn); 00175 break; 00176 00177 case OPR_PAREN: 00178 ty = WN_Tree_Type(WN_kid0(wn)); 00179 break; 00180 00181 case OPR_ADD: 00182 /* We make an attempt at retaining pointer types for ptr 00183 * arithmetics. If either one of the operands is a pointer, 00184 * then return this as the type of the expression, otherwise 00185 * return the type indicated by the opc_rtype. 00186 */ 00187 if (WN_rtype(wn) == Pointer_Mtype) { 00188 ty = WN_Tree_Type(WN_kid0(wn)); 00189 if (!TY_Is_Pointer(ty)) { 00190 ty = WN_Tree_Type(WN_kid1(wn)); 00191 if (!TY_Is_Pointer(ty)) 00192 ty = MTYPE_To_TY(WN_rtype(wn)); 00193 } 00194 00195 #ifdef _BUILD_WHIRL2C 00196 /* Also check that the constant expression can be reduced */ 00197 if (TY_Is_Pointer(ty) && 00198 WN_Get_PtrAdd_Intconst(WN_kid0(wn), 00199 WN_kid1(wn), 00200 TY_pointed(ty)) == NULL) { 00201 ty = MTYPE_To_TY(WN_rtype(wn)); 00202 } 00203 #endif /* _BUILD_WHIRL2C */ 00204 } 00205 else { 00206 ty = MTYPE_To_TY(WN_rtype(wn)); 00207 } 00208 break; 00209 00210 case OPR_INTRINSIC_OP: 00211 if (WN_intrinsic(wn) == INTRN_TLD_ADDR) { 00212 //in this case we get its actual type from its arguments 00213 ty = WN_get_tld_type(wn); 00214 break; 00215 } 00216 00217 if (INTR_is_adrtmp(WN_intrinsic(wn))) { 00218 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL || 00219 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL) { 00220 ty = WN_Tree_Type(WN_kid0(WN_kid0(wn))); 00221 } else { 00222 ty = Stab_Pointer_To(WN_Tree_Type(WN_kid0(wn))); 00223 } 00224 } else if (INTR_is_valtmp(WN_intrinsic(wn))) { 00225 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL || 00226 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL) { 00227 ty = TY_pointed(WN_Tree_Type(WN_kid0(WN_kid0(wn)))); 00228 } else { 00229 ty = WN_Tree_Type(WN_kid0(wn)); 00230 } 00231 } else { 00232 ty = WN_intrinsic_return_ty(wn); 00233 } 00234 break; 00235 00236 case OPR_CVT: 00237 case OPR_NEG: 00238 case OPR_ABS: 00239 case OPR_SQRT: 00240 case OPR_REALPART: 00241 case OPR_IMAGPART: 00242 case OPR_RND: 00243 case OPR_TRUNC: 00244 case OPR_CEIL: 00245 case OPR_FLOOR: 00246 case OPR_BNOT: 00247 case OPR_LNOT: 00248 case OPR_SUB: 00249 case OPR_MPY: 00250 case OPR_DIV: 00251 case OPR_MOD: 00252 case OPR_REM: 00253 case OPR_MAX: 00254 case OPR_MIN: 00255 case OPR_BAND: 00256 case OPR_BIOR: 00257 case OPR_BXOR: 00258 case OPR_BNOR: 00259 case OPR_LAND: 00260 case OPR_LIOR: 00261 case OPR_CAND: 00262 case OPR_CIOR: 00263 case OPR_SHL: 00264 case OPR_ASHR: 00265 case OPR_LSHR: 00266 case OPR_COMPLEX: 00267 case OPR_RECIP: 00268 case OPR_RSQRT: 00269 case OPR_EQ: 00270 case OPR_NE: 00271 case OPR_GT: 00272 case OPR_GE: 00273 case OPR_LT: 00274 case OPR_LE: 00275 case OPR_CONST: 00276 case OPR_INTCONST: 00277 case OPR_DIVREM: 00278 case OPR_HIGHPART: 00279 case OPR_LOWPART: 00280 case OPR_HIGHMPY: 00281 ty = MTYPE_To_TY(WN_rtype(wn)); 00282 break; 00283 00284 case OPR_PARM: 00285 ty = WN_Tree_Type(WN_kid0(wn)); 00286 break; 00287 00288 case OPR_COMMA: 00289 ty = WN_Tree_Type(WN_kid1(wn)); 00290 break; 00291 00292 case OPR_RCOMMA: 00293 ty = WN_Tree_Type(WN_kid0(wn)); 00294 break; 00295 00296 case OPR_ALLOCA: 00297 ty = WN_ty(wn); 00298 break; 00299 00300 case OPR_STRCTFLD: 00301 // we need to get the pointer here 00302 // because the whirl documentation 00303 // claims the STRCTFLD operator 00304 // returns a pointer to the field. 00305 ty = Stab_Pointer_To(WN_ty(wn)); 00306 break; 00307 00308 default: 00309 ASSERT_FATAL(false, (DIAG_A_STRING, "Programming Error.")); 00310 } /* switch */ 00311 } 00312 00313 return ty; 00314 } 00315 00316 00317 TY_IDX 00318 Get_Field_Type(TY_IDX base, int field_id) 00319 { 00320 ASSERT_FATAL(TY_Is_Structured(base), 00321 (DIAG_A_STRING, "GET_FIELD_TYPE: non struct type")); 00322 00323 UINT cur_fld_id = 0; 00324 FLD_HANDLE fh = FLD_get_to_field(base, field_id, cur_fld_id); 00325 return FLD_type(fh); 00326 } 00327 00328 TY_IDX 00329 WN_GetRefObjType(const WN* wn) 00330 { 00331 TY_IDX ty = 0; 00332 OPERATOR opr = WN_operator(wn); 00333 00334 switch (opr) { 00335 case OPR_LDA: // type of referenced (returned) address 00336 case OPR_LDMA: 00337 ty = WN_ty(wn); 00338 break; 00339 00340 case OPR_LDID: // type of referenced object 00341 case OPR_LDBITS: { 00342 ty = WN_ty(wn); 00343 ST* st = WN_st(wn); 00344 TY_IDX st_ty = ST_type(st); 00345 if (st_ty != ty) { 00346 // this can actually happen when we back-translate portions 00347 // using WN sub trees from the original whirl (see the patchWN... methods) and the variable 00348 // in question has become active which obviously not reflected in the original whirl 00349 const char* nm=ST_name(st); 00350 DBGMSG_PUB(0, "Warning: WN_GetRefObjType: type mismatch detected for %s", nm); 00351 ty=st_ty; 00352 } 00353 break; 00354 } 00355 00356 case OPR_ILOAD: // type of referenced object 00357 case OPR_ILOADX: 00358 case OPR_MLOAD: // Priya added MLOAD case 00359 ty = WN_ty(wn); 00360 break; 00361 00362 // STOREs represent the left-hand-side expression 00363 case OPR_STID: // type of referenced lhs object 00364 case OPR_PSTID: 00365 case OPR_PSTORE: 00366 case OPR_STBITS: 00367 ty = WN_ty(wn); 00368 break; 00369 00370 case OPR_ISTORE: // type of referenced lhs object 00371 case OPR_ISTOREX: 00372 case OPR_ISTBITS: 00373 case OPR_MSTORE: // Priya added MSTORE case 00374 ty = TY_pointed(WN_ty(wn)); 00375 if (TY_is_f90_pointer(ty)) { 00376 ty = TY_pointed(ty); 00377 } 00378 if (TY_Is_Array(ty)) { 00379 ty = TY_AR_etype(ty); 00380 } 00381 break; 00382 00383 case OPR_STRCTFLD: 00384 ty = WN_ty(wn); 00385 break; 00386 00387 default: 00388 { 00389 // NOTE: MLOAD, MSTORE are not supported 00390 std::ostringstream msg; 00391 msg << "not implemented for opcode " 00392 << &OPERATOR_info [opr]._name [4]; 00393 ASSERT_FATAL(false, (DIAG_A_STRING, msg.str().c_str())); 00394 } 00395 break; 00396 } 00397 return ty; 00398 } 00399 00400 00401 TY_IDX 00402 WN_GetBaseObjType(const WN* wn) 00403 { 00404 TY_IDX ty = 0; 00405 OPERATOR opr = WN_operator(wn); 00406 00407 ST* st = NULL; 00408 switch (opr) { 00409 case OPR_LDA: 00410 case OPR_LDMA: 00411 st = WN_st(wn); 00412 ty = ST_type(st); 00413 if (TY_is_f90_pointer(ty)) { ty = TY_pointed(ty); } 00414 break; 00415 00416 case OPR_LDID: 00417 case OPR_LDBITS: 00418 st = WN_st(wn); 00419 ty = ST_type(st); 00420 break; 00421 00422 case OPR_ILOAD: 00423 case OPR_ILOADX: 00424 case OPR_MLOAD: // Priya added MLOAD case 00425 { 00426 WN* baseptr = WN_kid0(wn); // address expression as WN 00427 TY_IDX baseptr_ty = WN_Tree_Type(baseptr); 00428 ASSERT_FATAL((TY_kind(baseptr_ty) == KIND_POINTER), 00429 (DIAG_A_STRING, "Internal error: expected a pointer type")); 00430 ty = TY_pointed(baseptr_ty); 00431 // Note: neither WN_ty() nor TY_pointed(WN_load_addr_ty(wn)) 00432 // always give the base object. For example, for a reference 00433 // like F(i)%v, both return the type of v and not the type of 00434 // the structure. 00435 break; 00436 } 00437 00438 // ARRAYs 00439 case OPR_ARRAY: 00440 ty = WN_GetBaseObjType(WN_kid0(wn)); 00441 break; 00442 00443 // STOREs represent the left-hand-side expression 00444 case OPR_STID: 00445 case OPR_PSTID: 00446 case OPR_STBITS: 00447 st = WN_st(wn); 00448 ty = ST_type(st); 00449 break; 00450 00451 case OPR_ISTORE: 00452 case OPR_ISTOREX: 00453 case OPR_ISTBITS: 00454 case OPR_MSTORE: // Priya added MSTORE case 00455 { 00456 // Note: use WN_Tree_Type(baseptr) instead of WN_ty(wn) to find 00457 // type of baseptr because the former will attempt to interpret 00458 // pointer arithmetic, e.g., the this structure reference 00459 // "X(1)%a%y = ..." 00460 // F8ISTORE 0 T<38,anon_ptr.,8> 00461 // ... 00462 // U8ADD 00463 // U8ARRAY 1 48 00464 // U8U8LDID 0 <2,3,X> T<35,anon_ptr.,8> 00465 // I4INTCONST 2 (0x2) 00466 // I4INTCONST 1 (0x1) 00467 // U8INTCONST 8 (0x8) 00468 WN* baseptr = WN_kid1(wn); // address expression as WN 00469 TY_IDX baseptr_ty = WN_Tree_Type(baseptr); // was: WN_ty(wn) 00470 ty = TY_pointed(baseptr_ty); 00471 // This assertion is not always true, e.g. given this Fortan: 00472 // F(i)%v = y 00473 // and this WHIRL 00474 // F8ISTORE 0 T<29,anon_ptr.,8> 00475 // ... 00476 // U8ARRAY 1 16 (lhs) 00477 // U8U8LDID 0 <2,3,F> T<57,anon_ptr.,8> (base) 00478 // ... 00479 // because the baseptr_ty and baseptr types are different, the 00480 // structure element reference will implicitly take place! 00481 //FORTTK_ASSERT((baseptr_ty == WN_Tree_Type(baseptr)), 00482 // "Internal error: base pointer types are inconsistent"); 00483 break; 00484 } 00485 00486 case OPR_PSTORE: 00487 ty=WN_ty(wn); 00488 break; 00489 00490 case OPR_STRCTFLD: 00491 ty = WN_load_addr_ty(wn); 00492 break; 00493 00494 default: { 00495 // NOTE: MLOAD, MSTORE are not supported 00496 std::ostringstream msg; 00497 msg << "not implemented for opcode " 00498 << &OPERATOR_info [opr]._name [4]; 00499 ASSERT_FATAL(false, (DIAG_A_STRING, msg.str().c_str())); 00500 break; 00501 } 00502 } 00503 return ty; 00504 } 00505 00506 TY_IDX 00507 WN_Call_Type(const WN* wn) 00508 { 00509 OPERATOR opr = WN_operator(wn); 00510 switch (opr) { 00511 case OPR_CALL: 00512 return ST_pu_type(WN_st(wn)); 00513 case OPR_ICALL: 00514 case OPR_VFCALL: 00515 return WN_ty(wn); 00516 case OPR_PICCALL: 00517 return ST_type(WN_st(wn)); 00518 case OPR_INTRINSIC_CALL: 00519 default: 00520 ASSERT_FATAL(false, (DIAG_A_STRING, "Programming Error.")); 00521 return 0; 00522 } 00523 } 00524 00525 00526 TY_IDX 00527 WN_Call_Return_Type(const WN* wn) 00528 { 00529 TY_IDX return_ty = 0; 00530 OPERATOR opr = WN_operator(wn); 00531 if (opr == OPR_INTRINSIC_CALL) { 00532 return_ty = WN_intrinsic_return_ty(wn); 00533 } else { 00534 if (opr == OPR_CALL && IntrinsicInfo::isIntrinsic(wn)) { 00535 // here come hacks for special cases that will be made obsolete by the move to Rose 00536 ST* st_p = WN_st(wn); 00537 const char* funcNm = ST_name(st_p); 00538 if (!strcmp(funcNm,"LEN") 00539 || 00540 !strcmp(funcNm,"ALLOCATED") 00541 || 00542 !strcmp(funcNm,"MAXVAL") 00543 || 00544 !strcmp(funcNm,"MAXLOC") 00545 || 00546 !strcmp(funcNm,"MINVAL") 00547 || 00548 !strcmp(funcNm,"SIZE") 00549 || 00550 !strcmp(funcNm,"SCAN") 00551 || 00552 !strcmp(funcNm,"SUM")) { 00553 return_ty=Stab_Mtype_To_Ty(OPCODE_rtype(WN_opcode(wn))); 00554 } 00555 else if (!strcmp(funcNm,"DBLE") 00556 || 00557 !strcmp(funcNm,"FLOAT") 00558 || 00559 !strcmp(funcNm,"REAL") 00560 || 00561 !strcmp(funcNm,"INT")) { 00562 return_ty=WN_GetExprType(WN_kid0(wn)); 00563 // this can be for instance an integer array 00564 if (TY_mtype(return_ty) != OPCODE_rtype(WN_opcode(wn))) { 00565 if (TY_Is_Pointer(return_ty)) { 00566 if (TY_Is_Array(TY_pointed(return_ty)) 00567 || 00568 TY_Is_Scalar(TY_pointed(return_ty))) { 00569 return_ty=TY_pointed(return_ty); 00570 } 00571 else { 00572 ASSERT_FATAL(false, (DIAG_UNIMPLEMENTED, "in WN_Call_Return_Type")); 00573 } 00574 } 00575 if (TY_Is_Array(return_ty)) { 00576 // make a fake type to return 00577 return_ty=Make_Array_Type(OPCODE_rtype(WN_opcode(wn)), 00578 (TY_arb(return_ty)).Entry()->dimension, 00579 1); 00580 } 00581 else 00582 return_ty=Stab_Mtype_To_Ty(OPCODE_rtype(WN_opcode(wn))); 00583 } 00584 } 00585 else if (!strcmp(funcNm,"LBOUND") 00586 || 00587 !strcmp(funcNm,"UBOUND")) { 00588 if (WN_kid_count(wn)==2) { // returns an integer 00589 return_ty=Stab_Mtype_To_Ty(OPCODE_rtype(WN_opcode(wn))); 00590 } 00591 else { // returns a vector 00592 // make up a type to return 00593 return_ty=Make_Array_Type(OPCODE_rtype(WN_opcode(wn)), 00594 1, // is just a vector 00595 (TY_arb(WN_GetExprType(WN_kid0(wn)))).Entry()->dimension); // length of the vector is the number of dimensions of the first argument 00596 } 00597 } 00598 else { 00599 return_ty=WN_GetExprType(WN_kid0(wn)); 00600 } 00601 } 00602 else { 00603 TY_IDX func_ty = WN_Call_Type(wn); 00604 return_ty = Func_Return_Type(func_ty); 00605 } 00606 } 00607 return return_ty; 00608 } 00609 00610 00611 INT 00612 WN_Call_First_Arg_Idx(const WN* wn) 00613 { 00614 INT idx = 0; 00615 OPERATOR opr = WN_operator(wn); 00616 if (opr == OPR_INTRINSIC_CALL) { 00617 TY_IDX return_ty = WN_Call_Return_Type(wn); 00618 BOOL return_to_param = WN_intrinsic_return_to_param(return_ty); 00619 idx = (return_to_param? 1 : 0); 00620 } else { 00621 TY_IDX func_ty = WN_Call_Type(wn); 00622 BOOL return_to_param = Func_Return_To_Param(func_ty); 00623 idx = (return_to_param) ? (Func_Return_Character(func_ty)? 2 : 1) : 0; 00624 } 00625 return idx; 00626 } 00627 00628 00629 INT 00630 WN_Call_Last_Arg_Idx(const WN* wn) 00631 { 00632 INT idx = WN_kid_count(wn) - 1; // default 00633 00634 OPERATOR opr = WN_operator(wn); 00635 switch (opr) { 00636 case OPR_ICALL: 00637 case OPR_VFCALL: 00638 case OPR_PICCALL: 00639 idx = WN_kid_count(wn) - 2; 00640 break; 00641 default: 00642 break; // fall through 00643 } 00644 return idx; 00645 } 00646 00647 00648 const char * 00649 WN_intrinsic_name(INTRINSIC intr_opc) 00650 { 00651 const char *name = NULL; 00652 Is_True(INTRINSIC_FIRST<=intr_opc && intr_opc<=INTRINSIC_LAST, 00653 ("Intrinsic Opcode (%d) out of range", intr_opc)); 00654 00655 if (INTRN_high_level_name(intr_opc) != NULL) { 00656 name = INTRN_high_level_name(intr_opc); 00657 } else { 00658 name = get_intrinsic_name(intr_opc); 00659 } 00660 00661 return name; 00662 } 00663 00664 00665 TY_IDX 00666 WN_intrinsic_return_ty(const WN* call) 00667 { 00668 TY_IDX ret_ty = 0; 00669 00670 OPERATOR opr = WN_operator(call); 00671 ASSERT_FATAL(opr == OPR_INTRINSIC_CALL || opr == OPR_INTRINSIC_OP, 00672 (DIAG_A_STRING, "Programming Error!")); 00673 00674 INTRINSIC intr_opc = (INTRINSIC)WN_intrinsic(call); 00675 switch (INTRN_return_kind(intr_opc)) { 00676 case IRETURN_UNKNOWN: { 00677 /* Use the opcode to get the type */ 00678 OPCODE opc = WN_opcode(call); 00679 ret_ty = Stab_Mtype_To_Ty(OPCODE_rtype(opc)); 00680 break; 00681 } 00682 case IRETURN_V: 00683 ret_ty = Stab_Mtype_To_Ty(MTYPE_V); 00684 break; 00685 case IRETURN_I1: 00686 ret_ty = Stab_Mtype_To_Ty(MTYPE_I1); 00687 break; 00688 case IRETURN_I2: 00689 ret_ty = Stab_Mtype_To_Ty(MTYPE_I2); 00690 break; 00691 case IRETURN_I4: 00692 ret_ty = Stab_Mtype_To_Ty(MTYPE_I4); 00693 break; 00694 case IRETURN_I8: 00695 ret_ty = Stab_Mtype_To_Ty(MTYPE_I8); 00696 break; 00697 case IRETURN_U1: 00698 ret_ty = Stab_Mtype_To_Ty(MTYPE_U1); 00699 break; 00700 case IRETURN_U2: 00701 ret_ty = Stab_Mtype_To_Ty(MTYPE_U2); 00702 break; 00703 case IRETURN_U4: 00704 ret_ty = Stab_Mtype_To_Ty(MTYPE_U4); 00705 break; 00706 case IRETURN_U8: 00707 ret_ty = Stab_Mtype_To_Ty(MTYPE_U8); 00708 break; 00709 case IRETURN_F4: 00710 ret_ty = Stab_Mtype_To_Ty(MTYPE_F4); 00711 break; 00712 case IRETURN_F8: 00713 ret_ty = Stab_Mtype_To_Ty(MTYPE_F8); 00714 break; 00715 case IRETURN_FQ: 00716 ret_ty = Stab_Mtype_To_Ty(MTYPE_FQ); 00717 break; 00718 case IRETURN_C4: 00719 ret_ty = Stab_Mtype_To_Ty(MTYPE_C4); 00720 break; 00721 case IRETURN_C8: 00722 ret_ty = Stab_Mtype_To_Ty(MTYPE_C8); 00723 break; 00724 case IRETURN_CQ: 00725 ret_ty = Stab_Mtype_To_Ty(MTYPE_CQ); 00726 break; 00727 case IRETURN_PV: 00728 ret_ty = Stab_Pointer_To(Stab_Mtype_To_Ty(MTYPE_V)); 00729 break; 00730 case IRETURN_PU1: 00731 ret_ty = Stab_Pointer_To(Stab_Mtype_To_Ty(MTYPE_U1)); 00732 break; 00733 case IRETURN_DA1: 00734 ret_ty = WN_Tree_Type(WN_kid0(call)); 00735 break; 00736 case IRETURN_M: 00737 ret_ty = Stab_Mtype_To_Ty(MTYPE_M); 00738 break; 00739 default: 00740 ASSERT_FATAL(false, (DIAG_A_STRING, "Programming Error.")); 00741 ret_ty = Stab_Mtype_To_Ty(MTYPE_V); 00742 break; 00743 } 00744 00745 return ret_ty; 00746 } /* WN_intrinsic_return_ty */ 00747 00748 00749 BOOL 00750 WN_intrinsic_return_to_param(TY_IDX return_ty) 00751 { 00752 // Assume there is only one case when the return value cannot be 00753 // passed through registers: a quad precision complex number. 00754 return (TY_mtype(return_ty) == MTYPE_CQ); 00755 } 00756 00757 00758 WN * 00759 WN_Get_PtrAdd_Intconst(WN* wn0, WN* wn1, TY_IDX pointed_ty) 00760 { 00761 /* We make an attempt at retaining pointer types for ptr 00762 * additions, where we expect the ptr expression to be of 00763 * one of the following forms: 00764 * 00765 * 1) ptr + expr 00766 * 2) ptr + expr*const 00767 * 3) ptr + const 00768 * 00769 * where const must be a multiple of the size of the pointed_ty 00770 * and only abscent when the size is 1. If this pattern is not 00771 * found, then return NULL; otherwise return the const expression, 00772 * if one is found, or the integral expression when size==1. 00773 */ 00774 WN *intconst = NULL; 00775 00776 /* Identify the integral expression */ 00777 if (!TY_Is_Pointer(WN_Tree_Type(wn0))) 00778 intconst = wn0; 00779 else if (!TY_Is_Pointer(WN_Tree_Type(wn1))) 00780 intconst = wn1; 00781 00782 /* Get the constant expression */ 00783 if (intconst != NULL && TY_size(pointed_ty) > 1) 00784 { 00785 /* Identify the integral constant expression */ 00786 if (WN_operator(intconst) == OPR_MPY) 00787 { 00788 if (WN_operator(WN_kid0(intconst)) == OPR_INTCONST) 00789 intconst = WN_kid0(intconst); 00790 else if (WN_operator(WN_kid1(intconst)) == OPR_INTCONST) 00791 intconst = WN_kid1(intconst); 00792 else 00793 intconst = NULL; 00794 } 00795 else if (WN_operator(intconst) != OPR_INTCONST) 00796 intconst = NULL; 00797 } 00798 00799 /* Make sure the constant expression is a multiple of the size of type 00800 * pointed to. 00801 */ 00802 if (TY_size(pointed_ty) == 0 || /* incomplete type */ 00803 (intconst != NULL && 00804 WN_operator(intconst) == OPR_INTCONST && 00805 WN_const_val(intconst)%TY_size(pointed_ty) != 0LL)) 00806 { 00807 intconst = NULL; 00808 } 00809 return intconst; 00810 } /* WN_Get_PtrAdd_Intconst */ 00811 00812 static TY_IDX 00813 WN_get_tld_type(const WN* wn) 00814 { 00815 //wn must be TLD_ADDR(...) 00816 WN* kid = WN_kid0(WN_kid0(wn)); 00817 TY_IDX result_ty = WN_Tree_Type(kid); 00818 switch (TY_kind(result_ty)) { 00819 case KIND_ARRAY: { 00820 TY_IDX new_ty; 00821 int dim = 1; 00822 for (new_ty = TY_etype(result_ty); TY_kind(new_ty) == KIND_ARRAY; new_ty = TY_etype(new_ty), dim++); 00823 for (;dim > 0; new_ty = Make_Pointer_Type(new_ty), dim--); 00824 return new_ty; 00825 } 00826 case KIND_STRUCT: 00827 if (WN_field_id(kid) != 0) { 00828 return Make_Pointer_Type(Get_Field_Type(result_ty, WN_field_id(kid))); 00829 } 00830 return Make_Pointer_Type(result_ty); 00831 case KIND_POINTER: { 00832 //need to handle ptr to shared data as a speical case 00833 TY_IDX pointed = TY_pointed(result_ty); 00834 if (TY_is_shared(pointed)) { 00835 if (TY_kind(pointed) != KIND_VOID && 00836 Get_Type_Block_Size(pointed) <= 1) { 00837 return Make_Pointer_Type(Make_Pointer_Type(pshared_ptr_idx)); 00838 } else { 00839 return Make_Pointer_Type(Make_Pointer_Type(shared_ptr_idx)); 00840 } 00841 } 00842 //fall thru to the default case if not shared 00843 } 00844 default: 00845 return Make_Pointer_Type(result_ty); 00846 } 00847 } 00848 00849 TY_IDX 00850 WN_GetExprType(const WN* wn) { 00851 TY_IDX ty = MTYPE_To_TY(MTYPE_V); // default is void 00852 if (wn == NULL) 00853 return ty; 00854 00855 OPERATOR opr = WN_operator(wn); 00856 00857 if (OPERATOR_is_stmt(opr)) { 00858 // ------------------------------------------------------- 00859 // Statements 00860 // ------------------------------------------------------- 00861 if (OPERATOR_is_call(opr)) { 00862 // CALLs: statements and expressions (in VH WHIRL) 00863 ty = WN_Call_Return_Type(wn); 00864 } 00865 else if (OPERATOR_is_store(opr)) { 00866 // STOREs: return type of lhs referenced *object* 00867 ty = WN_GetRefObjType(wn); 00868 } 00869 } 00870 else if (OPERATOR_is_expression(opr)) { 00871 // ------------------------------------------------------- 00872 // Expressions 00873 // ------------------------------------------------------- 00874 switch (opr) { 00875 00876 // LOADs 00877 // LOADs 00878 case OPR_LDA: 00879 case OPR_LDMA: 00880 case OPR_LDID: 00881 case OPR_LDBITS: 00882 ty = WN_GetRefObjType(wn); 00883 break; 00884 case OPR_ILOAD: 00885 case OPR_ILOADX: // type of referenced object 00886 ty = WN_GetExprType(WN_kid0(wn)); 00887 break; 00888 00889 case OPR_MLOAD: // type of referenced object 00890 // There is not much we can do about this case 00891 if (WN_operator(WN_kid1(wn)) == OPR_INTCONST && 00892 TY_Is_Structured(TY_pointed(WN_ty(wn)))) { 00893 00894 /* WEI: for field accesses, get the type of the field */ 00895 if (WN_field_id(wn) != 0) { 00896 ty = Get_Field_Type(TY_pointed(WN_ty(wn)), WN_field_id(wn)); 00897 } else { 00898 ty = Stab_Get_Mload_Ty(TY_pointed(WN_ty(wn)), 00899 WN_load_offset(wn), 00900 WN_const_val(WN_kid1(wn))); 00901 } 00902 } else { 00903 ty = TY_pointed(WN_ty(wn)); 00904 } 00905 break; 00906 00907 // ARRAYs 00908 case OPR_ARRSECTION: 00909 case OPR_ARRAYEXP: 00910 case OPR_ARRAY_CONSTRUCT: 00911 case OPR_IMPLIED_DO: 00912 ty = WN_GetExprType(WN_kid0(wn)); 00913 break; 00914 00915 case OPR_ARRAY: 00916 ty = WN_Tree_Type(WN_kid0(wn)); 00917 if (!TY_Is_Pointer(ty)) { 00918 /* Create a pointer to be treated as an array when also used 00919 * as the base-type of this OPC_ARRAY. This must be handled 00920 * very carefully in WN2C_array(). 00921 */ 00922 ty = Stab_Pointer_To(Stab_Array_Of(MTYPE_To_TY(MTYPE_U1), 00923 WN_element_size(wn))); 00924 } 00925 else if (!TY_ptr_as_array(Ty_Table[ty]) && TY_Is_Array(TY_pointed(ty))) { 00926 ty = Stab_Pointer_To(TY_AR_etype(TY_pointed(ty))); 00927 } 00928 break; 00929 00930 case OPR_TAS: 00931 ty = WN_ty(wn); 00932 break; 00933 00934 case OPR_SELECT: 00935 // We make an attempt at retaining pointer types for ptr 00936 // arithmetics. 00937 if (WN_rtype(wn) == Pointer_Mtype) { 00938 ty = WN_Tree_Type(WN_kid0(wn)); 00939 if (!TY_Is_Pointer(ty)) { 00940 ty = WN_Tree_Type(WN_kid1(wn)); 00941 if (!TY_Is_Pointer(ty)) 00942 ty = MTYPE_To_TY(WN_rtype(wn)); 00943 } 00944 } else 00945 ty = MTYPE_To_TY(WN_rtype(wn)); 00946 break; 00947 00948 case OPR_CVTL: 00949 ty = WN_Cvtl_Ty(wn); 00950 break; 00951 00952 case OPR_PAREN: 00953 ty = WN_GetExprType(WN_kid0(wn)); 00954 break; 00955 00956 case OPR_INTRINSIC_OP: 00957 if (WN_intrinsic(wn) == INTRN_TLD_ADDR) { 00958 //in this case we get its actual type from its arguments 00959 ty = WN_get_tld_type(wn); 00960 break; 00961 } 00962 00963 if (INTR_is_adrtmp(WN_intrinsic(wn))) { 00964 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL || 00965 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL) { 00966 ty = WN_Tree_Type(WN_kid0(WN_kid0(wn))); 00967 } else { 00968 ty = Stab_Pointer_To(WN_Tree_Type(WN_kid0(wn))); 00969 } 00970 } else if (INTR_is_valtmp(WN_intrinsic(wn))) { 00971 if (WN_opcode(WN_kid0(wn)) == OPC_VCALL || 00972 WN_opcode(WN_kid0(wn)) == OPC_VINTRINSIC_CALL) { 00973 ty = TY_pointed(WN_Tree_Type(WN_kid0(WN_kid0(wn)))); 00974 } else { 00975 ty = WN_Tree_Type(WN_kid0(wn)); 00976 } 00977 } else { 00978 ty = WN_intrinsic_return_ty(wn); 00979 } 00980 break; 00981 00982 case OPR_CVT: 00983 case OPR_NEG: 00984 case OPR_ABS: 00985 case OPR_SQRT: 00986 case OPR_REALPART: 00987 case OPR_IMAGPART: 00988 case OPR_RND: 00989 case OPR_TRUNC: 00990 case OPR_CEIL: 00991 case OPR_FLOOR: 00992 case OPR_BNOT: 00993 case OPR_LNOT: 00994 case OPR_BAND: 00995 case OPR_BIOR: 00996 case OPR_BXOR: 00997 case OPR_BNOR: 00998 case OPR_LAND: 00999 case OPR_LIOR: 01000 case OPR_CAND: 01001 case OPR_CIOR: 01002 case OPR_SHL: 01003 case OPR_ASHR: 01004 case OPR_LSHR: 01005 case OPR_COMPLEX: 01006 case OPR_RECIP: 01007 case OPR_RSQRT: 01008 case OPR_EQ: 01009 case OPR_NE: 01010 case OPR_GT: 01011 case OPR_GE: 01012 case OPR_LT: 01013 case OPR_LE: 01014 case OPR_CONST: 01015 case OPR_INTCONST: 01016 case OPR_DIVREM: 01017 case OPR_HIGHPART: 01018 case OPR_LOWPART: 01019 case OPR_HIGHMPY: 01020 ty = MTYPE_To_TY(WN_rtype(wn)); 01021 break; 01022 01023 case OPR_ADD: 01024 case OPR_SUB: 01025 case OPR_MPY: 01026 case OPR_DIV: 01027 case OPR_MOD: 01028 case OPR_REM: 01029 case OPR_MAX: 01030 case OPR_MIN: { 01031 // look at the operands 01032 TY_IDX ty1=WN_GetExprType(WN_kid0(wn)); 01033 TY_IDX ty2=WN_GetExprType(WN_kid1(wn)); 01034 if (TY_kind(ty1) == KIND_ARRAY) 01035 ty=ty1; 01036 else if (TY_Is_Pointer(ty1) 01037 && 01038 TY_kind(TY_pointed(ty1)) == KIND_ARRAY) 01039 ty=TY_pointed(ty1); 01040 else if (TY_kind(ty2) == KIND_ARRAY) 01041 ty=ty2; 01042 else if (TY_Is_Pointer(ty2) 01043 && 01044 TY_kind(TY_pointed(ty2)) == KIND_ARRAY) 01045 ty=TY_pointed(ty2); 01046 else 01047 ty=MTYPE_To_TY(WN_rtype(wn)); 01048 break; 01049 } 01050 01051 case OPR_PARM: 01052 if (WN_operator(WN_kid0(wn))==OPR_ILOAD || WN_operator(WN_kid0(wn))==OPR_ARRSECTION) { 01053 ty = WN_GetExprType(WN_kid0(WN_kid0(wn))); 01054 } 01055 else { 01056 ty = WN_GetExprType(WN_kid0(wn)); 01057 } 01058 break; 01059 01060 case OPR_COMMA: 01061 ty = WN_Tree_Type(WN_kid1(wn)); 01062 break; 01063 01064 case OPR_RCOMMA: 01065 ty = WN_Tree_Type(WN_kid0(wn)); 01066 break; 01067 01068 case OPR_ALLOCA: 01069 ty = WN_ty(wn); 01070 break; 01071 01072 case OPR_STRCTFLD: 01073 // we need to get the pointer here 01074 // because the whirl documentation 01075 // claims the STRCTFLD operator 01076 // returns a pointer to the field. 01077 ty = Stab_Pointer_To(WN_ty(wn)); 01078 break; 01079 01080 default: 01081 ASSERT_FATAL(false, (DIAG_A_STRING, "Programming Error.")); 01082 } /* switch */ 01083 } 01084 01085 return ty; 01086 }