OpenADFortTk (basic)
src/lib/support/Open64IRInterface/wn_attr.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines