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 // 25-Aug-96: Original Version 00042 // 00043 // Description: 00044 // Routines used for error checking of reshaped array portions 00045 // passed as function arguments. 00046 // 00047 // ==================================================================== 00048 // ==================================================================== 00049 00050 #include "defs.h" // standard definitions 00051 #include "wn.h" // WN 00052 #include "wn_util.h" // WN_COPY, WN_INSERT 00053 #include "targ_const.h" // Host_To_Targ_String 00054 #include "symtab_idx.h" // ST_IDX etc 00055 #include "symtab.h" // ST, TY 00056 #include "symtab_access.h" 00057 #include "opcode.h" // OPCODE_make_op 00058 #include "strtab.h" // Save_Str 00059 #include "config_targ.h" // Pointer_type 00060 #include "const.h" // Gen_String_Sym 00061 #include "dra_demangle.h" // DRA_Demangle_Func 00062 #include "dra_export.h" // Find_Return_Registers 00063 #include "dra_ec.h" // CART_ offsets 00064 #include "dra_internal.h" 00065 00066 // =================================================================== 00067 // 00068 // Exported variables 00069 // 00070 // =================================================================== 00071 00072 TY_IDX DRA_EC_struct_ptr_ty = (TY_IDX) NULL; 00073 00074 #define OPC_UNKNOWN OPCODE_UNKNOWN 00075 00076 static OPCODE Ldid_Opcode [MTYPE_LAST + 1] = { 00077 OPC_UNKNOWN, /* MTYPE_UNKNOWN */ 00078 OPC_UNKNOWN, /* MTYPE_UNKNOWN */ 00079 OPC_I4I1LDID, /* MTYPE_I1 */ 00080 OPC_I4I2LDID, /* MTYPE_I2 */ 00081 OPC_I4I4LDID, /* MTYPE_I4 */ 00082 OPC_I8I8LDID, /* MTYPE_I8 */ 00083 OPC_U4U1LDID, /* MTYPE_U1 */ 00084 OPC_U4U2LDID, /* MTYPE_U2 */ 00085 OPC_U4U4LDID, /* MTYPE_U4 */ 00086 OPC_U8U8LDID, /* MTYPE_U8 */ 00087 OPC_F4F4LDID, /* MTYPE_F4 */ 00088 OPC_F8F8LDID, /* MTYPE_F8 */ 00089 OPC_UNKNOWN, /* MTYPE_F10 */ 00090 OPC_UNKNOWN, /* MTYPE_F16 */ 00091 OPC_UNKNOWN, /* MTYPE_STR */ 00092 OPC_FQFQLDID, /* MTYPE_FQ */ 00093 OPC_UNKNOWN, /* MTYPE_M */ 00094 OPC_C4C4LDID, /* MTYPE_C4 */ 00095 OPC_C8C8LDID, /* MTYPE_C8 */ 00096 OPC_CQCQLDID, /* MTYPE_CQ */ 00097 OPC_UNKNOWN /* MTYPE_V */ 00098 }; 00099 00100 00101 00102 // =================================================================== 00103 // 00104 // Local function prototypes 00105 // 00106 // =================================================================== 00107 00108 static WN* Gen_Malloc_Cart (WN* block, 00109 WN* insert_wn, 00110 INT32 size, 00111 ST* cart_st); 00112 00113 static void Gen_Free_Cart (WN* block, 00114 WN* prev_wn, 00115 WN* stid_wn, 00116 ST* cart_st); 00117 00118 static WN* Gen_Call_Array (WN* block, 00119 WN* prev_wn, 00120 WN* array_wn, 00121 ST* func_st, 00122 ST* retval_st); 00123 00124 static WN* Get_Array_Dim_Size (TY& array_ty, 00125 INT dim); 00126 00127 static ST* Create_Local_ST (char *name, TY_IDX ty); 00128 00129 static ST* Declare_Func_N_Arg (char* ty_name, 00130 char* st_name, 00131 TY_IDX ret_ty, 00132 INT nargs, 00133 TY_IDX ty_array[]); 00134 00135 00136 00137 // =================================================================== 00138 // 00139 // File static variables 00140 // 00141 // =================================================================== 00142 00143 static ST* ECHT_Check = NULL; 00144 static ST* ECHT_Compare = NULL; 00145 00146 00147 // =================================================================== 00148 // 00149 // Exported function defintions 00150 // 00151 // =================================================================== 00152 00153 00154 // =================================================================== 00155 // 00156 // Function Name: DRA_EC_Declare_Types 00157 // 00158 // Description: Declare types of data structures used in 00159 // error-checking of reshaped array portions 00160 // passed as arguments. 00161 // 00162 // =================================================================== 00163 00164 void 00165 DRA_EC_Declare_Types () 00166 { 00167 // First declare the desired type of the runtime structure. 00168 00169 // declare an array of INT64 00170 TY_IDX I8_ty = Be_Type_Tbl(MTYPE_I8); 00171 TY_IDX index_array_ty_idx; 00172 TY& index_array_ty = New_TY (index_array_ty_idx); 00173 00174 ARB_HANDLE new_ari = New_ARB (); 00175 ARB_Init (new_ari, 1, 1, 1); 00176 Set_ARB_first_dimen(new_ari); 00177 Set_ARB_last_dimen(new_ari); 00178 Set_ARB_const_lbnd(new_ari); 00179 Set_ARB_lbnd_val(new_ari,0); 00180 Set_ARB_const_ubnd(new_ari); 00181 Set_ARB_ubnd_val(new_ari,9); 00182 Set_ARB_const_stride(new_ari); 00183 Set_ARB_stride_val(new_ari,TY_size(I8_ty)); 00184 00185 TY_Init (index_array_ty, 10*TY_size(I8_ty), KIND_ARRAY, MTYPE_UNKNOWN, Save_Str("INDEX_ARRAY_TY")); 00186 Set_TY_arb(index_array_ty, new_ari); 00187 Set_TY_align (index_array_ty_idx, 8); 00188 index_array_ty.Set_etype(I8_ty); 00189 00190 FLD_HANDLE first_field = New_FLD (); 00191 00192 FLD_Init (first_field, Save_Str("array_base"), I8_ty, CART_array_base); 00193 00194 FLD_HANDLE field = New_FLD (); 00195 FLD_Init (field, Save_Str("ndims"), I8_ty, CART_ndims); 00196 00197 field = New_FLD (); 00198 FLD_Init (field, Save_Str("element_size"), I8_ty, CART_element_size); 00199 00200 field = New_FLD (); 00201 FLD_Init (field, Save_Str("index"), index_array_ty_idx, CART_index); 00202 Set_FLD_last_field(field); 00203 00204 // declare a struct with the above field list 00205 TY_IDX ec_struct_ty_idx; 00206 TY& ec_struct_ty = New_TY(ec_struct_ty_idx); 00207 00208 TY_Init (ec_struct_ty, 3*TY_size(I8_ty) + TY_size(index_array_ty), KIND_STRUCT, MTYPE_M, Save_Str("DRA_EC_STRUCT_TY")); 00209 Set_TY_fld(ec_struct_ty, first_field); 00210 Set_TY_align (ec_struct_ty_idx, 8); 00211 00212 DRA_EC_struct_ptr_ty = Make_Pointer_Type ( ec_struct_ty_idx, TRUE ); 00213 Set_TY_ptr_as_array(Ty_Table[DRA_EC_struct_ptr_ty]); 00214 00215 00216 TY_IDX voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V), TRUE); 00217 ECHT_Check = Declare_Func_N_Arg (".__dsm_echt_check", 00218 "__dsm_echt_check", 00219 voidpty, 00220 1, 00221 &voidpty); 00222 00223 TY_IDX string_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1), TRUE); 00224 TY_IDX arg_ty[4] = {voidpty, voidpty, string_ty, string_ty}; 00225 ECHT_Compare = Declare_Func_N_Arg (".__dsm_echt_compare", 00226 "__dsm_echt_compare", 00227 Be_Type_Tbl(MTYPE_V), 00228 4, 00229 arg_ty); 00230 } 00231 00232 00233 00234 // =================================================================== 00235 // 00236 // Function Name: DRA_EC_Array_Portion_Parms 00237 // 00238 // Description: Recognize all array parameters, and check if they are 00239 // reshaped portions. If so, generate runtime check. 00240 // 00241 // =================================================================== 00242 00243 void 00244 DRA_EC_Array_Portion_Parms (WN* func_wn, WN* entry_wn) 00245 { 00246 Is_True (WN_opcode(func_wn) == OPC_FUNC_ENTRY && 00247 (WN_opcode(entry_wn) == OPC_FUNC_ENTRY || 00248 WN_opcode(entry_wn) == OPC_ALTENTRY), 00249 ("EC_Parms: expected a FUNC_ENTRY or ALTENTRY node\n")); 00250 00251 // insert into block after prev_wn, or before insert_wn 00252 // 00253 WN *block = WN_func_body(func_wn); 00254 WN *prev_wn = Get_Preamble_End(entry_wn); 00255 WN *insert_wn = WN_next(prev_wn); 00256 00257 // For FUNC_ENTRY num_formals is kid_count-3 00258 // For ALTEENTRY num_formals is kid_count 00259 // 00260 INT num_formals = (WN_opcode(entry_wn) == OPC_FUNC_ENTRY ? 00261 WN_num_formals(entry_wn) : WN_kid_count(entry_wn)); 00262 00263 for (INT i = 0; i < num_formals; i++) { 00264 00265 ST& formal_st = St_Table[WN_st_idx(WN_formal(entry_wn, i))]; 00266 TY_IDX array_ty = (TY_IDX) NULL; 00267 TY& formal_ty = Ty_Table[ST_type(formal_st)]; 00268 Is_True (ST_sclass(formal_st) == SCLASS_FORMAL || 00269 ST_sclass(formal_st) == SCLASS_FORMAL_REF, 00270 ("EC_Parms: IDNAME(%s) not a FORMAL\n", ST_name(formal_st))); 00271 00272 BOOL array_parm = FALSE; 00273 switch (ST_sclass(formal_st)) { 00274 case SCLASS_FORMAL: 00275 if (TY_kind(formal_ty) == KIND_POINTER && 00276 TY_kind(TY_pointed(formal_ty)) == KIND_ARRAY) { 00277 array_ty = TY_pointed(formal_ty); 00278 array_parm = TRUE; 00279 } 00280 break; 00281 case SCLASS_FORMAL_REF: 00282 if (TY_kind(formal_ty) == KIND_ARRAY) { 00283 array_ty = ST_type(formal_st); 00284 array_parm = TRUE; 00285 } 00286 break; 00287 } 00288 if (!array_parm) continue; 00289 00290 // 00291 // Here we could also check that the array is not reshaped! 00292 // 00293 00294 // ok -- it is an array parameter 00295 // 00296 char name[64]; 00297 (void) strcpy(name, "$cart_formal_"); 00298 (void) strncat(name, ST_name(WN_st(entry_wn)), 20); 00299 (void) strncat(name, ST_name(formal_st), 20); 00300 ST *cart_st = Create_Local_ST(name, DRA_EC_struct_ptr_ty); 00301 00302 // Generate a check to see if in the hash-table 00303 // 00304 WN *array_ldid = WN_Ldid(Pointer_type, (WN_OFFSET)0, &formal_st, ST_type(formal_st)); 00305 00306 WN* stid_wn = 00307 Gen_Call_Array (block, prev_wn, array_ldid, ECHT_Check, cart_st); 00308 prev_wn = stid_wn; 00309 00310 WN* cart_ldid_wn = WN_Ldid (Pointer_type, 0, cart_st, ST_type(cart_st)); 00311 WN* if_wn = WN_CreateIf(cart_ldid_wn, WN_CreateBlock(), WN_CreateBlock()); 00312 WN_INSERT_BlockAfter (block, prev_wn, if_wn); 00313 WN_Set_Linenum (if_wn, WN_Get_Linenum(prev_wn)); 00314 prev_wn = if_wn; 00315 00316 // cart->array_base = array-base 00317 array_ldid = WN_COPY_Tree(array_ldid); 00318 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn); 00319 WN *istore_wn = 00320 WN_CreateIstore (OPCODE_make_op (OPR_ISTORE, MTYPE_V, Pointer_type), 00321 CART_array_base, 00322 Make_Pointer_Type(Be_Type_Tbl(Pointer_type), TRUE), 00323 array_ldid, 00324 cart_ldid_wn); 00325 WN_Set_Linenum (istore_wn, WN_Get_Linenum(insert_wn)); 00326 WN_INSERT_BlockBefore (WN_then(if_wn), NULL, istore_wn); 00327 insert_wn = WN_first(WN_then(if_wn)); 00328 prev_wn = insert_wn; 00329 00330 // now generate allocate cart before it 00331 INT ndims = TY_AR_ndims(Ty_Table[array_ty]); 00332 WN* cart_stid_wn = 00333 Gen_Malloc_Cart (WN_then(if_wn), insert_wn, 8*(ndims+3), cart_st); 00334 00335 00336 OPCODE istore_op = OPCODE_make_op(OPR_ISTORE, MTYPE_V, MTYPE_I8); 00337 TY_IDX I8ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8), TRUE); 00338 00339 // cart->ndims = ndims 00340 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn); 00341 istore_wn = WN_CreateIstore (istore_op, 00342 CART_ndims, 00343 I8ptr_ty, 00344 WN_Intconst(MTYPE_I8, ndims), 00345 cart_ldid_wn); 00346 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn)); 00347 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn); 00348 prev_wn = istore_wn; 00349 00350 // cart->element_size = element_size 00351 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn); 00352 istore_wn = WN_CreateIstore(istore_op, 00353 CART_element_size, 00354 I8ptr_ty, 00355 WN_Intconst(MTYPE_I8, 00356 TY_size(TY_AR_etype(array_ty))), 00357 cart_ldid_wn); 00358 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn)); 00359 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn); 00360 prev_wn = istore_wn; 00361 00362 for (INT j=0; j<ndims; j++) { 00363 // cart->dim-size = dim-size 00364 WN* size_wn = Get_Array_Dim_Size (Ty_Table[array_ty], j); 00365 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn); 00366 istore_wn = WN_CreateIstore (istore_op, 00367 CART_index+8*j, 00368 I8ptr_ty, 00369 size_wn, 00370 cart_ldid_wn); 00371 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn)); 00372 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn); 00373 prev_wn = istore_wn; 00374 } 00375 00376 // call compare cart 00377 { 00378 array_ldid = WN_COPY_Tree(array_ldid); 00379 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn); 00380 00381 WN* call_wn = WN_Create(OPCODE_make_op(OPR_CALL, MTYPE_V, MTYPE_V), 4); 00382 00383 // array 00384 WN* parm_wn = WN_CreateParm (Pointer_type, 00385 array_ldid, 00386 Be_Type_Tbl(Pointer_type), 00387 WN_PARM_BY_VALUE); 00388 WN_kid(call_wn, 0) = parm_wn; 00389 00390 // cart 00391 parm_wn = WN_CreateParm (Pointer_type, 00392 cart_ldid_wn, 00393 Be_Type_Tbl(Pointer_type), 00394 WN_PARM_BY_VALUE); 00395 WN_kid(call_wn, 1) = parm_wn; 00396 00397 // function name 00398 OPCODE lda_op = OPCODE_make_op (OPR_LDA, Pointer_type, MTYPE_V); 00399 TY_IDX string_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1), TRUE); 00400 00401 char *func_name = DRA_Demangle_Func(ST_name(WN_st(entry_wn))); 00402 if (func_name == NULL) { 00403 func_name = ST_name(WN_st(entry_wn)); 00404 } 00405 TCON tcon = 00406 Host_To_Targ_String (MTYPE_STRING, func_name, strlen(func_name)+1); 00407 ST *rt_func_name = 00408 Gen_String_Sym (&tcon, Be_Type_Tbl(MTYPE_STRING), FALSE); 00409 WN *func_name_wn = WN_CreateLda (lda_op, 0, string_ty, rt_func_name); 00410 parm_wn = WN_CreateParm (Pointer_type, 00411 func_name_wn, 00412 Be_Type_Tbl(Pointer_type), 00413 WN_PARM_BY_REFERENCE); 00414 WN_kid(call_wn, 2) = parm_wn; 00415 00416 // array name 00417 char* array_name = ST_name(formal_st); 00418 tcon = 00419 Host_To_Targ_String (MTYPE_STRING, array_name, strlen(array_name)+1); 00420 ST *rt_array_name = 00421 Gen_String_Sym (&tcon, Be_Type_Tbl(MTYPE_STRING), FALSE); 00422 WN *array_name_wn = WN_CreateLda (lda_op, 0, string_ty, rt_array_name); 00423 parm_wn = WN_CreateParm (Pointer_type, 00424 array_name_wn, 00425 Be_Type_Tbl(Pointer_type), 00426 WN_PARM_BY_REFERENCE); 00427 WN_kid(call_wn, 3) = parm_wn; 00428 00429 WN_st_idx(call_wn) = ST_st_idx(ECHT_Compare); 00430 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, call_wn); 00431 prev_wn = call_wn; 00432 } 00433 00434 Gen_Free_Cart (WN_then(if_wn), prev_wn, cart_stid_wn, cart_st); 00435 prev_wn = if_wn; 00436 } 00437 } 00438 00439 00440 00441 // =================================================================== 00442 // 00443 // Function Name: Get_Array_Dim_Size 00444 // 00445 // Description: Given an array type and a dimension number, 00446 // return a WHIRL tree for the size of that dimension. 00447 // 00448 // =================================================================== 00449 00450 static WN* 00451 Get_Array_Dim_Size (TY& array_ty, INT dim) 00452 { 00453 INT ndims = TY_AR_ndims(array_ty); 00454 00455 if ((!TY_AR_const_lbnd(array_ty, dim)) && 00456 (TY_AR_lbnd_val(array_ty, dim) == 0)) 00457 return WN_Intconst (MTYPE_I8, -1); 00458 if ((!TY_AR_const_ubnd(array_ty, dim)) && 00459 (TY_AR_ubnd_val(array_ty, dim) == 0)) 00460 return WN_Intconst (MTYPE_I8, -1); 00461 00462 WN* lb; 00463 if (TY_AR_const_lbnd(array_ty, dim)) { 00464 lb = WN_Intconst(MTYPE_I8, TY_AR_lbnd_val(array_ty, dim)); 00465 } 00466 else { 00467 ST_IDX lbnd_st_idx = TY_AR_lbnd_var(array_ty,dim); 00468 ST& lbnd_st = St_Table [lbnd_st_idx]; 00469 TY_IDX lbnd_ty_idx = ST_type (lbnd_st); 00470 00471 TYPE_ID lty_mtype = TY_mtype (Ty_Table [lbnd_ty_idx]); 00472 lb = WN_CreateLdid (Ldid_Opcode [lty_mtype], 00473 (WN_OFFSET)0, &lbnd_st, lbnd_ty_idx); 00474 } 00475 00476 WN* ub; 00477 if (TY_AR_const_ubnd(array_ty, dim)) { 00478 ub = WN_Intconst(MTYPE_I8, TY_AR_ubnd_val(array_ty, dim)); 00479 } 00480 else { 00481 ST_IDX ubnd_st_idx = TY_AR_ubnd_var(array_ty,dim); 00482 ST& ubnd_st = St_Table [ubnd_st_idx]; 00483 TY_IDX ubnd_ty_idx = ST_type (ubnd_st); 00484 00485 TYPE_ID lty_mtype = TY_mtype (Ty_Table [ubnd_ty_idx]); 00486 ub = WN_CreateLdid (Ldid_Opcode [lty_mtype], 00487 (WN_OFFSET)0, &ubnd_st, ubnd_ty_idx); 00488 } 00489 00490 WN* size_wn = WN_Add (MTYPE_I8, 00491 WN_Sub (MTYPE_I8, ub, lb), 00492 WN_Intconst (MTYPE_I8, 1)); 00493 return size_wn; 00494 } 00495 00496 00497 00498 00499 // =================================================================== 00500 // 00501 // Function Name: Gen_Malloc_Cart 00502 // 00503 // Description: Generate cart_st = malloc(size) 00504 // Insert code into block before insert_wn 00505 // Return the STID of cart_st 00506 // 00507 // =================================================================== 00508 00509 static WN* 00510 Gen_Malloc_Cart (WN* block, WN* insert_wn, INT32 size, ST* cart_st) 00511 { 00512 OPCODE icallop = OPCODE_make_op(OPR_INTRINSIC_CALL, Pointer_type, MTYPE_V); 00513 WN* call_wn = WN_Create(icallop, 1); 00514 WN_intrinsic(call_wn) = 00515 Pointer_Size == 8 ? INTRN_U8I8MALLOC : INTRN_U4I4MALLOC; 00516 WN_Set_Linenum (call_wn, WN_Get_Linenum(insert_wn)); 00517 WN* size_wn = WN_Intconst (Pointer_Size == 8 ? MTYPE_I8 : MTYPE_I4, size); 00518 WN* parm_wn = WN_CreateParm(MTYPE_U8, size_wn, 00519 Be_Type_Tbl(MTYPE_U8), WN_PARM_BY_VALUE); 00520 WN_kid0(call_wn) = parm_wn; 00521 00522 WN_INSERT_BlockBefore (block, insert_wn, call_wn); 00523 PREG_NUM rreg1, rreg2; 00524 ST* rst = Find_Return_Registers(Pointer_type, &rreg1, &rreg2); 00525 FmtAssert(rreg1 != 0 && rreg2 == 0, ("Bad pointer type ret regs")); 00526 00527 WN *ldid_wn = WN_CreateLdid (OPCODE_make_op(OPR_LDID, 00528 Pointer_type, 00529 Pointer_type), 00530 rreg1, 00531 rst, 00532 DRA_EC_struct_ptr_ty); 00533 00534 OPCODE op = OPCODE_make_op(OPR_STID, MTYPE_V, Pointer_type); 00535 WN *stid_wn = WN_CreateStid(op, 0, cart_st, ST_type(cart_st), ldid_wn); 00536 00537 WN_Set_Linenum (stid_wn, WN_Get_Linenum(insert_wn)); 00538 WN_INSERT_BlockBefore (block, insert_wn, stid_wn); 00539 00540 return stid_wn; 00541 } 00542 00543 00544 00545 00546 // =================================================================== 00547 // 00548 // Function Name: Gen_Free_Cart 00549 // 00550 // Description: Generate free(cart_st) and insert code into block 00551 // after prev_wn 00552 // 00553 // =================================================================== 00554 00555 static void 00556 Gen_Free_Cart (WN* block, WN* prev_wn, WN* stid_wn, ST *cart_st) 00557 { 00558 OPCODE icallop = OPCODE_make_op(OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V); 00559 WN* call_wn = WN_Create(icallop, 1); 00560 WN_intrinsic(call_wn) = Pointer_Size == 8 ? INTRN_U8FREE : INTRN_U4FREE; 00561 00562 WN* ldid_wn = WN_Ldid (Pointer_type, 0, cart_st, ST_type(cart_st)); 00563 WN* parm_wn = WN_CreateParm(Pointer_type, 00564 ldid_wn, 00565 Be_Type_Tbl(Pointer_type), 00566 WN_PARM_BY_REFERENCE); 00567 WN_kid0(call_wn) = parm_wn; 00568 00569 WN_Set_Linenum (call_wn, WN_Get_Linenum(prev_wn)); 00570 WN_INSERT_BlockAfter (block, prev_wn, call_wn); 00571 } 00572 00573 00574 00575 00576 // =================================================================== 00577 // 00578 // Function Name: Gen_Call_Array 00579 // 00580 // Description: Given an ldid in array_wn, generate a call to the 00581 // given function with a single argument, array_wn. 00582 // Store the return value of the function into retval_st, 00583 // and return the stid. 00584 // Insert generated code into block after prev_wn. 00585 // 00586 // =================================================================== 00587 00588 static WN* 00589 Gen_Call_Array (WN* block, 00590 WN* prev_wn, 00591 WN* array_wn, 00592 ST* func_st, 00593 ST* retval_st) 00594 { 00595 WN* call_wn = WN_Create(OPCODE_make_op(OPR_CALL, Pointer_type, MTYPE_V), 1); 00596 WN* parm_wn = WN_CreateParm (Pointer_type, 00597 array_wn, 00598 Be_Type_Tbl(Pointer_type), 00599 WN_PARM_BY_VALUE); 00600 WN_kid(call_wn, 0) = parm_wn; 00601 WN_st_idx(call_wn) = ST_st_idx(func_st); 00602 00603 WN_INSERT_BlockAfter (block, prev_wn, call_wn); 00604 prev_wn = call_wn; 00605 00606 // generate retval assignment into retval_st 00607 // 00608 PREG_NUM rreg1, rreg2; 00609 ST* rst = Find_Return_Registers(Pointer_type, &rreg1, &rreg2); 00610 FmtAssert(rreg1 != 0 && rreg2 == 0, ("Bad pointer type ret regs")); 00611 00612 WN *ldid_wn = WN_CreateLdid (OPCODE_make_op(OPR_LDID, 00613 Pointer_type, 00614 Pointer_type), 00615 rreg1, 00616 rst, 00617 DRA_EC_struct_ptr_ty); 00618 00619 OPCODE op = OPCODE_make_op(OPR_STID, MTYPE_V, Pointer_type); 00620 WN *stid_wn = WN_CreateStid(op, 0, retval_st, ST_type(retval_st), ldid_wn); 00621 00622 WN_Set_Linenum (stid_wn, WN_Get_Linenum(prev_wn)); 00623 WN_INSERT_BlockAfter (block, prev_wn, stid_wn); 00624 00625 return stid_wn; 00626 } 00627 00628 00629 00630 // =================================================================== 00631 // 00632 // Create local ST* entry with a given name and type 00633 // 00634 // =================================================================== 00635 00636 static ST* 00637 Create_Local_ST(char *name, TY_IDX ty) 00638 { 00639 ST *st = New_ST(CURRENT_SYMTAB); 00640 Set_ST_is_temp_var(st); 00641 ST_Init(st, Save_Str(name), CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, ty); 00642 /* TODO:: 00643 Set_ST_pt_to_unique_mem(st); 00644 */ 00645 return st; 00646 } 00647 00648 00649 // =================================================================== 00650 // 00651 // Declare prototype for a function with N arguments 00652 // 00653 // =================================================================== 00654 00655 static ST* 00656 Declare_Func_N_Arg (char* ty_name, 00657 char* st_name, 00658 TY_IDX ret_ty, 00659 INT nargs, 00660 TY_IDX ty_array[]) 00661 { 00662 // Create function prototype 00663 // 00664 TY_IDX voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V), TRUE); 00665 00666 TY_IDX func_ty; 00667 TY& ty = New_TY(func_ty); 00668 PU_IDX pu_idx; 00669 PU& pu = New_PU (pu_idx); 00670 00671 TYLIST_IDX idx = Tylist_Table.Insert(ret_ty); 00672 for (INT i = 0; i < nargs; i++) { 00673 Tylist_Table.Insert(ty_array[i]); 00674 } 00675 Tylist_Table.Insert(0); 00676 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str(ty_name)); 00677 Set_TY_tylist (ty, idx); 00678 00679 Set_TY_align (func_ty, TY_align(voidpty)); 00680 PU_Init (pu, func_ty, GLOBAL_SYMTAB + 1); 00681 00682 // Make an ST: add function to global symbol table 00683 // 00684 ST *func_st = New_ST ( GLOBAL_SYMTAB ); 00685 ST_Init(func_st, Save_Str(st_name), CLASS_FUNC, SCLASS_EXTERN, EXPORT_PREEMPTIBLE, (TY_IDX) pu_idx); 00686 00687 return func_st; 00688 }