Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
dra_ec.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 //  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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines