Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 */