00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifdef USE_PCH
00065 #include "lno_pch.h"
00066 #endif // USE_PCH
00067 #pragma hdrstop
00068
00069 const static char *source_file = __FILE__;
00070 const static char *rcs_id = "$Source$ $Revision$";
00071
00072 #ifndef _NEW_SYMTAB
00073
00074 #include <sys/types.h>
00075 #include "lnopt_main.h"
00076 #include "config_targ.h"
00077 #include "stab.h"
00078 #include "strtab.h"
00079 #include "stblock.h"
00080 #include "lwn_util.h"
00081 #include "dep.h"
00082 #include "lnoutils.h"
00083 #include "targ_const.h"
00084 #include "const.h"
00085 #include "glob.h"
00086
00087 typedef HASH_TABLE<ST*, BOOL> STBOOL_HASH_TABLE;
00088 typedef STACK<WN*> STACK_OF_WN;
00089
00090 static void Instrument_Array_Ref(WN *, BOOL,INT, STACK_OF_WN *, STBOOL_HASH_TABLE *);
00091 static void Instrument_Address(WN *address, BOOL is_load, INT num_bytes);
00092 static ST *Create_MemTools_Store();
00093 static ST *Create_MemTools_Load();
00094 static WN *Find_Statement(WN *wn);
00095 static INT Size(OPCODE opcode);
00096 static void Instrument_Rec(WN *, STACK_OF_WN *, STACK_OF_WN *, STBOOL_HASH_TABLE *);
00097 static void Remove_Locals(STACK_OF_WN *, STACK_OF_WN *);
00098 static ST *Create_Local_Array_ST (TY* ty, INT num);
00099 static void Process_Base(WN *, INT , STACK_OF_WN *);
00100 static ST *dim_sizes;
00101
00102 #define MAX_ARRAY_DIMS 8
00103
00104 void Instrument_Mem_Sim(WN *func_nd)
00105 {
00106 dim_sizes = NULL;
00107 MEM_POOL_Push(&LNO_local_pool);
00108
00109 STACK_OF_WN *local_arrays = CXX_NEW(STACK_OF_WN(&LNO_local_pool),
00110 &LNO_local_pool);
00111
00112
00113 STACK_OF_WN *return_points = CXX_NEW(STACK_OF_WN(&LNO_local_pool),
00114 &LNO_local_pool);
00115
00116 STBOOL_HASH_TABLE *array_hash =
00117 CXX_NEW(STBOOL_HASH_TABLE(200,&LNO_local_pool),&LNO_local_pool);
00118
00119 Instrument_Rec(func_nd,local_arrays,return_points,array_hash);
00120
00121 WN *last_statement = WN_last(WN_func_body(func_nd));
00122 if (WN_opcode(last_statement) != OPC_RETURN) return_points->Push(last_statement);
00123 Remove_Locals(local_arrays,return_points);
00124 CXX_DELETE(local_arrays,&LNO_local_pool);
00125 CXX_DELETE(return_points,&LNO_local_pool);
00126 CXX_DELETE(array_hash,&LNO_local_pool);
00127 MEM_POOL_Pop(&LNO_local_pool);
00128 }
00129
00130 static void Instrument_Rec(WN *wn, STACK_OF_WN *local_arrays,
00131 STACK_OF_WN *return_points, STBOOL_HASH_TABLE *array_hash)
00132 {
00133 OPCODE opcode = WN_opcode(wn);
00134 if (opcode == OPC_BLOCK) {
00135 WN *kid = WN_first (wn);
00136 while (kid) {
00137 Instrument_Rec(kid,local_arrays,return_points,array_hash);
00138 kid = WN_next(kid);
00139 }
00140 } else {
00141 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00142 Instrument_Rec(WN_kid(wn,kidno),local_arrays,return_points,array_hash);
00143 }
00144 if (opcode == OPC_RETURN) {
00145 return_points->Push(wn);
00146 } else if (OPCODE_is_load(opcode) && (OPCODE_operator(opcode) != OPR_LDID)) {
00147 if (WN_operator(WN_kid0(wn)) == OPR_ARRAY) {
00148 Instrument_Array_Ref(WN_kid0(wn),TRUE,Size(opcode),
00149 local_arrays,array_hash);
00150 } else {
00151 Instrument_Address(WN_kid0(wn),TRUE,Size(opcode));
00152 }
00153 } else if (OPCODE_is_store(opcode) && (OPCODE_operator(opcode) != OPR_STID)) {
00154 if (WN_operator(WN_kid1(wn)) == OPR_ARRAY) {
00155 Instrument_Array_Ref(WN_kid1(wn),FALSE,Size(opcode),
00156 local_arrays,array_hash);
00157 } else {
00158 Instrument_Address(WN_kid1(wn),FALSE,Size(opcode));
00159 }
00160 }
00161 }
00162 }
00163
00164
00165 static INT Size(OPCODE opcode)
00166 {
00167 switch(OPCODE_desc(opcode)) {
00168 case MTYPE_I1: case MTYPE_U1: return 1;
00169 case MTYPE_I2: case MTYPE_U2: return 2;
00170 case MTYPE_I4: case MTYPE_U4: case MTYPE_F4: return 4;
00171 case MTYPE_I8: case MTYPE_U8: case MTYPE_F8: case MTYPE_C4: return 8;
00172 #if defined(TARG_IA64)
00173 case MTYPE_F10:
00174 #endif
00175 case MTYPE_C8: case MTYPE_FQ: return 16;
00176 case MTYPE_CQ: return 32;
00177 }
00178 return 0;
00179 }
00180
00181
00182
00183
00184 static WN *Find_Statement(WN *wn)
00185 {
00186 while (OPCODE_is_expression(WN_opcode(wn))) wn = LWN_Get_Parent(wn);
00187 return wn;
00188 }
00189
00190
00191 static ST *Create_MemTools_Load()
00192 {
00193 static st *result=NULL;
00194 if (result) return result;
00195
00196 TY *func_ty = New_TY(TRUE);
00197 TY_kind(func_ty) = KIND_FUNCTION;
00198 TY_btype(func_ty) = MTYPE_UNKNOWN;
00199 Set_TY_has_prototype(func_ty);
00200 TY_ftinfo(func_ty) = New_FTI (2, TRUE );
00201 TYLIST *parms = TY_parms(func_ty);
00202 TYLIST_item(&parms[0]) = Be_Type_Tbl(Pointer_type);
00203 TYLIST_item(&parms[1]) = Be_Type_Tbl(Pointer_type);
00204 TY_name(func_ty) = Save_Str(".MemoryTools_Load");
00205 TY *voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V));
00206 TY_size(func_ty) = TY_size(voidpty);
00207 TY_align(func_ty) = TY_align(voidpty);
00208 TY_ret_type(func_ty) = Be_Type_Tbl(MTYPE_V);
00209 Enter_TY (func_ty);
00210
00211
00212 result = New_ST ( TRUE );
00213 ST_name(result) = Save_Str("MemoryTools_Load");
00214 ST_class(result) = CLASS_FUNC;
00215 Set_ST_sclass(result,SCLASS_EXTERN);
00216 Set_ST_export(result, EXPORT_PREEMPTIBLE);
00217 ST_type(result) = func_ty;
00218 Enter_ST ( result);
00219 return result;
00220 }
00221
00222
00223 static ST *Create_MemTools_Store()
00224 {
00225 static st *result=NULL;
00226 if (result) return result;
00227
00228 TY *func_ty = New_TY(TRUE);
00229 TY_kind(func_ty) = KIND_FUNCTION;
00230 TY_btype(func_ty) = MTYPE_UNKNOWN;
00231 Set_TY_has_prototype(func_ty);
00232 TY_ftinfo(func_ty) = New_FTI (2, TRUE );
00233 TYLIST *parms = TY_parms(func_ty);
00234 TYLIST_item(&parms[0]) = Be_Type_Tbl(Pointer_type);
00235 TYLIST_item(&parms[1]) = Be_Type_Tbl(Pointer_type);
00236 TY_name(func_ty) = Save_Str(".MemoryTools_Store");
00237 TY *voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V));
00238 TY_size(func_ty) = TY_size(voidpty);
00239 TY_align(func_ty) = TY_align(voidpty);
00240 TY_ret_type(func_ty) = Be_Type_Tbl(MTYPE_V);
00241 Enter_TY (func_ty);
00242
00243
00244 result = New_ST ( TRUE );
00245 ST_name(result) = Save_Str("MemoryTools_Store");
00246 ST_class(result) = CLASS_FUNC;
00247 Set_ST_sclass(result,SCLASS_EXTERN);
00248 Set_ST_export(result, EXPORT_PREEMPTIBLE);
00249 ST_type(result) = func_ty;
00250 Enter_ST ( result);
00251 return result;
00252 }
00253
00254
00255 static ST *Create_MemTools_MakeGlobal()
00256 {
00257 static st *result=NULL;
00258 if (result) return result;
00259
00260 TY *func_ty = New_TY(TRUE);
00261 TY_kind(func_ty) = KIND_FUNCTION;
00262 TY_btype(func_ty) = MTYPE_UNKNOWN;
00263 Set_TY_has_prototype(func_ty);
00264 TY_ftinfo(func_ty) = New_FTI (6, TRUE );
00265 TYLIST *parms = TY_parms(func_ty);
00266 TYLIST_item(&parms[0]) = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1));
00267 TYLIST_item(&parms[1]) = Be_Type_Tbl(Pointer_type);
00268 TYLIST_item(&parms[2]) = Be_Type_Tbl(Pointer_type);
00269 TYLIST_item(&parms[3]) = Be_Type_Tbl(Pointer_type);
00270 TYLIST_item(&parms[4]) = Make_Pointer_Type(Be_Type_Tbl(Pointer_type));
00271 TYLIST_item(&parms[5]) = Be_Type_Tbl(MTYPE_I4);
00272 TY_name(func_ty) = Save_Str(".MemoryTools_MakeGlobal");
00273 TY *voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V));
00274 TY_size(func_ty) = TY_size(voidpty);
00275 TY_align(func_ty) = TY_align(voidpty);
00276 TY_ret_type(func_ty) = Be_Type_Tbl(MTYPE_V);
00277 Enter_TY (func_ty);
00278
00279
00280 result = New_ST ( TRUE );
00281 ST_name(result) = Save_Str("MemoryTools_MakeGlobal");
00282 ST_class(result) = CLASS_FUNC;
00283 Set_ST_sclass(result,SCLASS_EXTERN);
00284 Set_ST_export(result, EXPORT_PREEMPTIBLE);
00285 ST_type(result) = func_ty;
00286 Enter_ST ( result);
00287 return result;
00288 }
00289
00290
00291 static ST *Create_MemTools_MakeLocal()
00292 {
00293 static st *result=NULL;
00294 if (result) return result;
00295
00296 TY *func_ty = New_TY(TRUE);
00297 TY_kind(func_ty) = KIND_FUNCTION;
00298 TY_btype(func_ty) = MTYPE_UNKNOWN;
00299 Set_TY_has_prototype(func_ty);
00300 TY_ftinfo(func_ty) = New_FTI (7, TRUE );
00301 TYLIST *parms = TY_parms(func_ty);
00302 TYLIST_item(&parms[0]) = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1));
00303 TYLIST_item(&parms[1]) = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1));
00304 TYLIST_item(&parms[2]) = Be_Type_Tbl(Pointer_type);
00305 TYLIST_item(&parms[3]) = Be_Type_Tbl(Pointer_type);
00306 TYLIST_item(&parms[4]) = Be_Type_Tbl(Pointer_type);
00307 TYLIST_item(&parms[5]) = Make_Pointer_Type(Be_Type_Tbl(Pointer_type));
00308 TYLIST_item(&parms[6]) = Be_Type_Tbl(MTYPE_I4);
00309 TY_name(func_ty) = Save_Str(".MemoryTools_MakeLocal");
00310 TY *voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V));
00311 TY_size(func_ty) = TY_size(voidpty);
00312 TY_align(func_ty) = TY_align(voidpty);
00313 TY_ret_type(func_ty) = Be_Type_Tbl(MTYPE_V);
00314 Enter_TY (func_ty);
00315
00316
00317 result = New_ST ( TRUE );
00318 ST_name(result) = Save_Str("MemoryTools_MakeLocal");
00319 ST_class(result) = CLASS_FUNC;
00320 Set_ST_sclass(result,SCLASS_EXTERN);
00321 Set_ST_export(result, EXPORT_PREEMPTIBLE);
00322 ST_type(result) = func_ty;
00323 Enter_ST ( result);
00324 return result;
00325 }
00326
00327
00328 static ST *Create_MemTools_RemoveLocal()
00329 {
00330 static st *result=NULL;
00331 if (result) return result;
00332
00333 TY *func_ty = New_TY(TRUE);
00334 TY_kind(func_ty) = KIND_FUNCTION;
00335 TY_btype(func_ty) = MTYPE_UNKNOWN;
00336 Set_TY_has_prototype(func_ty);
00337 TY_ftinfo(func_ty) = New_FTI (1, TRUE );
00338 TYLIST *parms = TY_parms(func_ty);
00339 TYLIST_item(&parms[0]) = Make_Pointer_Type(Be_Type_Tbl(Pointer_type));
00340 TY_name(func_ty) = Save_Str(".MemoryTools_RemoveLocal");
00341 TY *voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V));
00342 TY_size(func_ty) = TY_size(voidpty);
00343 TY_align(func_ty) = TY_align(voidpty);
00344 TY_ret_type(func_ty) = Be_Type_Tbl(MTYPE_V);
00345 Enter_TY (func_ty);
00346
00347
00348 result = New_ST ( TRUE );
00349 ST_name(result) = Save_Str("MemoryTools_RemoveLocal");
00350 ST_class(result) = CLASS_FUNC;
00351 Set_ST_sclass(result,SCLASS_EXTERN);
00352 Set_ST_export(result, EXPORT_PREEMPTIBLE);
00353 ST_type(result) = func_ty;
00354 Enter_ST ( result);
00355 return result;
00356 }
00357
00358
00359
00360 static void Instrument_Address(WN *address, BOOL is_load, INT num_bytes)
00361 {
00362 WN *insertion_point = Find_Statement(address);
00363 WN *new_address = LWN_Copy_Tree(address);
00364 LWN_Copy_Def_Use(address,new_address,Du_Mgr);
00365 ST *func;
00366 if (is_load) {
00367 func = Create_MemTools_Load();
00368 } else {
00369 func = Create_MemTools_Store();
00370 }
00371 WN *call = WN_Create(OPC_VCALL,2);
00372 WN_st(call) = func;
00373 WN_linenum(call) = WN_linenum(insertion_point);
00374 WN_kid0(call) = LWN_CreateParm(Pointer_type,new_address,Be_Type_Tbl(Pointer_type),
00375 WN_PARM_BY_VALUE);
00376 LWN_Set_Parent(WN_kid0(call),call);
00377 WN_kid1(call) = LWN_CreateParm(Pointer_type,LWN_Make_Icon(Pointer_type,num_bytes),
00378 Be_Type_Tbl(Pointer_type),WN_PARM_BY_VALUE);
00379 LWN_Set_Parent(WN_kid1(call),call);
00380 LWN_Copy_Frequency(call,insertion_point);
00381 LWN_Insert_Block_Before(LWN_Get_Parent(insertion_point),insertion_point,
00382 call);
00383 }
00384
00385
00386
00387
00388 static void Instrument_Array_Ref(WN *address, BOOL is_load, INT num_bytes,
00389 STACK_OF_WN *local_arrays, STBOOL_HASH_TABLE *array_hash)
00390 {
00391 WN *base = WN_array_base(address);
00392 if (WN_operator(base) == OPR_LDA) {
00393 if (!array_hash->Find(WN_st(base))) {
00394 array_hash->Enter(WN_st(base),TRUE);
00395 Process_Base(base,num_bytes,local_arrays);
00396 }
00397 }
00398 WN *enclosing_loop = Enclosing_Do_Loop(address);
00399 INT depth;
00400 if (!enclosing_loop) {
00401 depth = -1;
00402 } else {
00403 depth = Do_Loop_Depth(enclosing_loop);
00404 }
00405 ACCESS_ARRAY *array = (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,address);
00406 if (!array) {
00407 Instrument_Address(address,is_load,num_bytes);
00408 return;
00409 }
00410 BOOL stride1 = TRUE;
00411 if (array->Too_Messy || (array->Non_Const_Loops() > depth) ) {
00412 stride1 = FALSE;
00413 }
00414 if (array->Num_Vec() > MAX_ARRAY_DIMS) {
00415 Instrument_Address(address,is_load,num_bytes);
00416 return;
00417 }
00418 for (INT i=0; i<array->Num_Vec()-1; i++) {
00419 ACCESS_VECTOR *av = array->Dim(i);
00420 if (av->Loop_Coeff(av->Nest_Depth()-1)) {
00421 stride1 = FALSE;
00422 }
00423 }
00424 ACCESS_VECTOR *av = array->Dim(i);
00425 if (av->Loop_Coeff(av->Nest_Depth()-1) != 1) {
00426 stride1 = FALSE;
00427 }
00428 if (!stride1) {
00429 Instrument_Address(address,is_load,num_bytes);
00430 return;
00431 }
00432
00433 WN *loop = Enclosing_Do_Loop(address);
00434 if (!loop) {
00435 Instrument_Address(address,is_load,num_bytes);
00436 return;
00437 }
00438 DO_LOOP_INFO *dli = Get_Do_Loop_Info(loop);
00439 ACCESS_VECTOR *Step = dli->Step;
00440 if (!Step->Is_Const() || (Step->Const_Offset != 1)) {
00441 Instrument_Address(address,is_load,num_bytes);
00442 return;
00443 }
00444 ACCESS_ARRAY *low_array = dli->LB;
00445 if (low_array->Too_Messy) {
00446 Instrument_Address(address,is_load,num_bytes);
00447 return;
00448 }
00449 for (i=0; i<low_array->Num_Vec(); i++) {
00450 ACCESS_VECTOR *av = low_array->Dim(i);
00451 if (av->Too_Messy) {
00452 Instrument_Address(address,is_load,num_bytes);
00453 return;
00454 }
00455 }
00456
00457 WN *trip_count = LWN_Loop_Trip_Count(loop);
00458 if (!trip_count) {
00459 Instrument_Address(address,is_load,num_bytes);
00460 return;
00461 }
00462
00463
00464 WN *size = LWN_CreateExp2(
00465 OPCODE_make_op(OPR_MPY, WN_rtype(trip_count),MTYPE_V),
00466 trip_count, LWN_Make_Icon(WN_rtype(trip_count),num_bytes));
00467
00468
00469
00470 WN *new_address = LWN_Copy_Tree(address);
00471 LWN_Copy_Def_Use(address,new_address,Du_Mgr);
00472
00473 Replace_Ldid_With_Exp_Copy(SYMBOL(WN_start(loop)),new_address,
00474 WN_kid0(WN_start(loop)),Du_Mgr);
00475
00476 ST *func;
00477 if (is_load) {
00478 func = Create_MemTools_Load();
00479 } else {
00480 func = Create_MemTools_Store();
00481 }
00482 WN *call = WN_Create(OPC_VCALL,2);
00483 WN_st(call) = func;
00484 WN_linenum(call) = WN_linenum(loop);
00485 WN_kid0(call) = LWN_CreateParm(Pointer_type,new_address,
00486 Be_Type_Tbl(Pointer_type), WN_PARM_BY_VALUE);
00487 LWN_Set_Parent(WN_kid0(call),call);
00488 WN_kid1(call) = LWN_CreateParm(Pointer_type,size,
00489 Be_Type_Tbl(Pointer_type),WN_PARM_BY_VALUE);
00490 LWN_Set_Parent(WN_kid1(call),call);
00491 LWN_Copy_Frequency(call,loop);
00492 LWN_Insert_Block_Before(LWN_Get_Parent(loop),loop,
00493 call);
00494
00495
00496 }
00497
00498
00499
00500 static void Remove_Locals(STACK_OF_WN *local_arrays,
00501 STACK_OF_WN *return_points)
00502 {
00503 ST *func_st = Create_MemTools_RemoveLocal();
00504 for (INT i=0; i<return_points->Elements(); i++) {
00505 WN *return_point = return_points->Bottom_nth(i);
00506 for (INT j=0; j<local_arrays->Elements(); j++) {
00507 WN *array = local_arrays->Bottom_nth(j);
00508 WN *call = WN_Create(OPC_VCALL,1);
00509 WN_st(call) = func_st;
00510 WN_kid0(call) = LWN_CreateParm(Pointer_type,LWN_Copy_Tree(array),
00511 Make_Pointer_Type(Be_Type_Tbl(Pointer_type)),WN_PARM_BY_REFERENCE);
00512 LWN_Set_Parent(WN_kid0(call),call);
00513 LWN_Insert_Block_Before(LWN_Get_Parent(return_point),return_point, call);
00514 }
00515 }
00516 }
00517
00518
00519 static void Process_Base(WN *base, INT num_bytes, STACK_OF_WN *local_arrays)
00520 {
00521 BOOL is_fortran;
00522 switch (SYMTAB_src_lang(Current_Symtab)) {
00523 case SYMTAB_F90_LANG:
00524 case SYMTAB_F77_LANG:
00525 is_fortran=TRUE;
00526 break;
00527 default: is_fortran=FALSE;
00528 }
00529
00530 WN *array = LWN_Get_Parent(base);
00531 ST *st = WN_st(base);
00532 BOOL is_local = FALSE;
00533 if (ST_symtab_id(st) == SYMTAB_id(Current_Symtab)) {
00534 if (ST_sclass(st) == SCLASS_AUTO || ST_sclass(st) == SCLASS_TEMP) {
00535 is_local = TRUE;
00536 local_arrays->Push(base);
00537 }
00538 }
00539
00540 WN *func_nd = base;
00541 while (LWN_Get_Parent(func_nd)) func_nd = LWN_Get_Parent(func_nd);
00542 WN *first_statement = WN_first(WN_func_body(func_nd));
00543
00544 if (!dim_sizes) {
00545 dim_sizes =
00546 Create_Local_Array_ST(Be_Type_Tbl(Pointer_type),MAX_ARRAY_DIMS);
00547 }
00548
00549
00550 for (INT i=0; i<WN_num_dim(array); i++) {
00551 WN *dim = WN_array_dim(array,i);
00552 Is_True(WN_operator(dim) == OPR_INTCONST,
00553 ("Non const dimension for a local or global array "));
00554 OPCODE op_array = OPCODE_make_op(OPR_ARRAY,Pointer_type,MTYPE_V);
00555 OPCODE lda_op = OPCODE_make_op(OPR_LDA,Pointer_type,MTYPE_V);
00556 WN *dim_array = WN_Create(op_array,3);
00557 WN_element_size(dim_array) = 4;
00558 WN_array_base(dim_array) = WN_CreateLda(lda_op,0,
00559 Make_Pointer_Type(ST_type(dim_sizes)) ,dim_sizes);
00560 LWN_Set_Parent(WN_array_base(dim_array),dim_array);
00561 if (is_fortran) {
00562 WN_array_index(dim_array,0) =
00563 LWN_Make_Icon(Pointer_type,WN_num_dim(array)-i-1);
00564 } else {
00565 WN_array_index(dim_array,0) = LWN_Make_Icon(Pointer_type,i);
00566 }
00567 LWN_Set_Parent(WN_array_index(dim_array,0),dim_array);
00568 WN_array_dim(dim_array,0) = LWN_Make_Icon(Pointer_type,MAX_ARRAY_DIMS);
00569 LWN_Set_Parent(WN_array_dim(dim_array,0),dim_array);
00570 WN *store = LWN_CreateIstore(
00571 OPCODE_make_op(OPR_ISTORE, MTYPE_V, Pointer_type),
00572 0,Make_Pointer_Type(Be_Type_Tbl(Pointer_type)),
00573 LWN_Make_Icon(Pointer_type,WN_const_val(dim)),
00574 dim_array);
00575 LWN_Insert_Block_Before(LWN_Get_Parent(first_statement),first_statement,
00576 store);
00577 }
00578 ST *func;
00579 INT func_name_kid = 0;
00580 if (is_local) {
00581 func = Create_MemTools_MakeLocal();
00582 func_name_kid++;
00583 } else {
00584 func = Create_MemTools_MakeGlobal();
00585 }
00586 WN *call = WN_Create(OPC_VCALL,6+func_name_kid);
00587 WN_st(call) = func;
00588
00589 TCON tc = Host_To_Targ_String ( MTYPE_STRING, ST_name(WN_st(base)), strlen(ST_name(WN_st(base)))+1);
00590 ST *string = Gen_String_Sym ( &tc, MTYPE_To_TY(MTYPE_STRING), FALSE );
00591 OPCODE lda_op = OPCODE_make_op(OPR_LDA,Pointer_type,MTYPE_V);
00592 WN *lda = WN_CreateLda(lda_op,0,Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1)),string);
00593
00594 WN_kid0(call) = LWN_CreateParm(Pointer_type,lda,
00595 Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1)),WN_PARM_BY_REFERENCE);
00596 LWN_Set_Parent(WN_kid0(call),call);
00597
00598 if (func_name_kid) {
00599 TCON tc = Host_To_Targ_String ( MTYPE_STRING,Cur_PU_Name,
00600 strlen(Cur_PU_Name)+1);
00601 ST *string = Gen_String_Sym ( &tc, MTYPE_To_TY(MTYPE_STRING), FALSE );
00602 OPCODE lda_op = OPCODE_make_op(OPR_LDA,Pointer_type,MTYPE_V);
00603 WN *lda = WN_CreateLda(lda_op,0,
00604 Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1)),string);
00605
00606 WN_kid1(call) = LWN_CreateParm(Pointer_type,lda,
00607 Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1)),WN_PARM_BY_REFERENCE);
00608 LWN_Set_Parent(WN_kid1(call),call);
00609 }
00610
00611 WN *address = LWN_Copy_Tree(base);
00612 WN_kid(call,1+func_name_kid) =
00613 LWN_CreateParm(Pointer_type,address,Be_Type_Tbl(Pointer_type),
00614 WN_PARM_BY_VALUE);
00615 LWN_Set_Parent(WN_kid(call,1+func_name_kid),call);
00616
00617 WN_kid(call,2+func_name_kid) =LWN_CreateParm(MTYPE_U4,
00618 LWN_Make_Icon(MTYPE_I4,WN_num_dim(array)),
00619 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
00620 LWN_Set_Parent(WN_kid(call,2+func_name_kid),call);
00621
00622 WN_kid(call,3+func_name_kid) =LWN_CreateParm(Pointer_type,
00623 LWN_Make_Icon(Pointer_type,num_bytes),
00624 Be_Type_Tbl(Pointer_type), WN_PARM_BY_VALUE);
00625 LWN_Set_Parent(WN_kid(call,3+func_name_kid),call);
00626
00627 lda_op = OPCODE_make_op(OPR_LDA,Pointer_type,MTYPE_V);
00628 lda = WN_CreateLda(lda_op,0,Make_Pointer_Type(ST_type(dim_sizes)),dim_sizes);
00629 WN_kid(call,4+func_name_kid) = LWN_CreateParm(Pointer_type,lda,
00630 Make_Pointer_Type(Be_Type_Tbl(Pointer_type)),WN_PARM_BY_REFERENCE);
00631 LWN_Set_Parent(WN_kid(call,4+func_name_kid),call);
00632
00633 WN_kid(call,5+func_name_kid) =
00634 LWN_CreateParm(MTYPE_I4,LWN_Make_Icon(MTYPE_I4,!is_fortran),
00635 Be_Type_Tbl(MTYPE_I4),WN_PARM_BY_VALUE);
00636 LWN_Set_Parent(WN_kid(call,5+func_name_kid),call);
00637
00638 LWN_Insert_Block_Before(LWN_Get_Parent(first_statement),first_statement,
00639 call);
00640
00641 }
00642
00643
00644 static ST* Create_Local_Array_ST (TY* ty, INT num) {
00645 char name[64];
00646 ST *st;
00647 TY *arr_ty;
00648 ARI *ari;
00649
00650 ari = New_ARI (1, FALSE);
00651 ARI_etype(ari) = ty;
00652 ARB_const_lbnd(ARI_bnd(ari, 0)) = TRUE;
00653 ARB_const_ubnd(ARI_bnd(ari, 0)) = TRUE;
00654 ARB_const_stride(ARI_bnd(ari, 0)) = TRUE;
00655 ARB_lbnd_val(ARI_bnd(ari, 0)) = 0;
00656 ARB_ubnd_val(ARI_bnd(ari, 0)) = num-1;
00657 ARB_stride_val(ARI_bnd(ari, 0)) = 1;
00658
00659
00660 arr_ty = New_TY(FALSE);
00661 TY_kind(arr_ty) = KIND_ARRAY;
00662 TY_btype(arr_ty) = MTYPE_M;
00663 TY_arinfo(arr_ty) = ari;
00664 sprintf (name, "tmp_num_dims");
00665 TY_name(arr_ty) = Save_Str(name);
00666 TY_size(arr_ty) = TY_size(ty)*num;
00667 TY_align(arr_ty) = 8;
00668 Enter_TY(arr_ty);
00669
00670
00671 st = New_ST(FALSE);
00672 ST_name(st) = Save_Str(name);
00673 ST_class(st) = CLASS_VAR;
00674 Set_ST_sclass(st, SCLASS_AUTO);
00675 Set_ST_is_temp_var(st);
00676 ST_type(st) = arr_ty;
00677 Enter_ST (st);
00678 Set_ST_pt_to_unique_mem(st);
00679 return st;
00680 }
00681
00682 #endif