Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wn_attr.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  07-Mar-95 - Original Version
00042  *
00043  * Description:
00044  *
00045  *   Get WN tree attributes, beyond those provided through 
00046  *   common/com/wn_core.h.
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 /*--------- Hidden utility to get type info about a cvtl node ---------*
00060  *---------------------------------------------------------------------*/
00061 
00062 static const MTYPE WN_Cvtl_Mtype[2/*is_signed*/][9/*byte-size*/] =
00063 {/* unsigned */
00064  {MTYPE_UNKNOWN,      /* 0 bytes */
00065   MTYPE_U1,           /* 1 byte  */
00066   MTYPE_U2,           /* 2 bytes */
00067   MTYPE_UNKNOWN,      /* 3 bytes */
00068   MTYPE_U4,           /* 4 bytes */
00069   MTYPE_UNKNOWN,      /* 5 bytes */
00070   MTYPE_UNKNOWN,      /* 6 bytes */
00071   MTYPE_UNKNOWN,      /* 7 bytes */
00072   MTYPE_U8},          /* 8 bytes */
00073  /* signed */
00074  {MTYPE_UNKNOWN,      /* 0 bytes */
00075   MTYPE_I1,           /* 1 byte  */
00076   MTYPE_I2,           /* 2 bytes */
00077   MTYPE_UNKNOWN,      /* 3 bytes */
00078   MTYPE_I4,           /* 4 bytes */
00079   MTYPE_UNKNOWN,      /* 5 bytes */
00080   MTYPE_UNKNOWN,      /* 6 bytes */
00081   MTYPE_UNKNOWN,      /* 7 bytes */
00082   MTYPE_I8}           /* 8 bytes */
00083 }; /* WN_Cvtl_Mtype */
00084 
00085 static TY_IDX
00086 WN_Cvtl_Ty(const WN *wn)
00087 {
00088    /* The type of a CVTL node is the return type scaled down to the
00089     * given bitsize.
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 } /* WN_Cvtl_Ty */
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 /*------------------------ Exported functions -------------------------
00109  *---------------------------------------------------------------------*/
00110 
00111 
00112 static TY_IDX
00113 WN_get_tld_type(const WN* wn) {
00114 
00115   //wn must be TLD_ADDR(...)
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     //need to handle ptr to shared data as a speical case
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     //fall thru to the default case if not shared
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    /* Count the number of nodes that references the object or address
00153     * denoted by the given ST.  Only count LDID, STID or LDA references.
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    } /*loop*/
00178    return counter;
00179 } /* WN_num_var_refs */
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       /* Use the opcode to get the type */
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 //#ifdef KEY 
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 //#endif
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 } /* WN_intrinsic_return_ty */
00278 
00279 
00280 BOOL 
00281 WN_intrinsic_return_to_param(TY_IDX return_ty)
00282 {
00283    /* We assume there is only one case when the return value
00284     * cannot be passed through registers, namely for a quad
00285     * precision complex number.
00286     */
00287    return (TY_mtype(return_ty) == MTYPE_CQ);
00288 
00289 } /* WN_intrinsic_return_to_param */
00290 
00291 
00292 WN *
00293 WN_Get_PtrAdd_Intconst(WN    *wn0, 
00294                        WN    *wn1, 
00295                        TY_IDX pointed_ty)
00296 {
00297    /* We make an attempt at retaining pointer types for ptr
00298     * additions, where we expect the ptr expression to be of
00299     * one of the following forms:
00300     *
00301     *    1)  ptr + expr
00302     *    2)  ptr + expr*const
00303     *    3)  ptr + const
00304     *
00305     * where const must be a multiple of the size of the pointed_ty
00306     * and only abscent when the size is 1. If this pattern is not 
00307     * found, then return NULL; otherwise return the const expression,
00308     * if one is found, or the integral expression when size==1.
00309     */
00310    WN *intconst = NULL;
00311          
00312    /* Identify the integral expression */
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    /* Get the constant expression */
00319    if (intconst != NULL && TY_size(pointed_ty) > 1)
00320    {
00321       /* Identify the integral constant expression */
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    /* Make sure the constant expression is a multiple of the size of type
00336     * pointed to.
00337     */
00338    if (TY_size(pointed_ty) == 0 ||    /* incomplete type */
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 } /* WN_Get_PtrAdd_Intconst */
00347 
00348 TY_IDX
00349 WN_Tree_Type(const WN *wn)
00350 {
00351    /* Return a TY that as closely as possible represents the type of the
00352     * given subexpression (wn).
00353     *
00354     * TY_is_logical() will only hold true when the TY is resolved from
00355     * a WN_ty or ST_ty attribute, not when it is resolved from an MTYPE.
00356     *
00357     * Pointer types may be created as a result of a call to this routine.
00358     */
00359 
00360    TY_IDX ty = Stab_Mtype_To_Ty(MTYPE_V); /* return value, default = void */
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           //WEI: for field accesses we return the type of the field
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          /* There is not much we can do about this case */
00386          if (WN_opc_operator(WN_kid1(wn)) == OPR_INTCONST &&
00387              TY_Is_Structured(TY_pointed(WN_ty(wn))))
00388          {
00389 
00390            /* WEI: for field accesses, get the type of the field */
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          /* Get the address type denoted by the base offset by the
00411           * given indexing expression. Note that we do handle
00412           * pointers as arrays when there is no ambiguity, and
00413           * we rely on the flag TY_ptr_as_array() to handle indexing
00414           * of an array of arrays.  The following should access the
00415           * fifth element, each element consisting of 17 ints:
00416           *
00417           *    int (*a)[17]; .... a[5] ....
00418           *
00419           * This will be represented as (OPR_ARRAY (OPR_LDID a) ...),
00420           * but, since the type of kid0 is ptr-to-arrayOfInts, we need
00421           * the flag TY_ptr_as_array or else the type of the ARRAY
00422           * node would be considered a ptr-to-ints (see also 
00423           * WN2C_array()).
00424           */
00425          ty = WN_Tree_Type(WN_kid0(wn));
00426 #if 0 //FMZ Aug 2005
00427          if (!TY_Is_Pointer(ty))
00428          {
00429             /* Create a pointer to be treated as an array when also used
00430              * as the base-type of this OPC_ARRAY.  This must be handled
00431              * very carefully in WN2C_array().
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          /* We make an attempt at retaining pointer types for ptr
00449           * arithmetics.
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          /* We make an attempt at retaining pointer types for ptr
00475           * arithmetics.  If either one of the operands is a pointer,
00476           * then return this as the type of the expression, otherwise
00477           * return the type indicated by the opc_rtype.
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             /* Also check that the constant expression can be reduced */
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           //in this case we get its actual type from its arguments
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          /* Only the above forms of expression nodes are handled here */
00612 /*       ErrMsg ( EC_Invalid_Case, "WN_Tree_Type", __LINE__ );*/
00613 /* since the cases of OPR list do not cover all the operators,
00614  * for some reason we need to keep the process going,
00615  * change to return the default value (void) now,will adjust 
00616  * it later based on case by case.
00617  *   -----fzhao
00618  */
00619        break;
00620       } /* switch */
00621    } /* else */
00622    return ty;
00623 } /* WN_Tree_Type */
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    /* See also the code in prp_wn_mngr.cxx
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          /* Remove any statement sequence enclosed by pragmas indicating
00651           * that we should skip the statements in w2c or w2f translation.
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                /* Get a skipped item info record.
00665                 */
00666                skip = &skip_info[*next_info_idx];
00667                *next_info_idx += 1;
00668 
00669                /* Record this skipped item.
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                /* Remove this skipped sequence of statements
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          } /* if a skip sequence is found */
00695       } /*if a block is found */
00696    } /* for each statement */
00697 } /* Remove_Skips */
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       /* Purple might insert instrumentation between the prev and next
00715        * nodes that used to surround the removed code segment.  We step
00716        * by any such inserted code, thus re-inserting the temporarily
00717        * removed code after the instrumentation.
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); /* Code inserted at beginning of block */
00723       while (prev != NULL && WN_next(prev) != NULL && prev != WN_prev(next))
00724          prev = WN_next(prev);
00725 
00726       /* Reinsert the temporarily removed code (after instrumentations)
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 } /* Restore_Skips */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines