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 #include <alloca.h>
00051 #include <elf.h>
00052
00053 #include "defs.h"
00054 #include "wn.h"
00055 #include "stab.h"
00056 #include "pu_info.h"
00057
00058 #include "opcode.h"
00059 #include "mempool.h"
00060 #include "cxx_memory.h"
00061 #include "wn_pragmas.h"
00062 #include "config_targ.h"
00063 #include "targ_sim.h"
00064 #include "erbe.h"
00065 #include "strtab.h"
00066 #include "wn_util.h"
00067 #include "dwarf_DST.h"
00068 #include "config.h"
00069 #include "dra_internal.h"
00070
00071
00072
00073
00074
00075
00076
00077
00078 static DRA_INFO* New_DRA (WN** pwn_addr,
00079 ST *array_st,
00080 TY_IDX array_ty,
00081 WN *block,
00082 WN *preamble);
00083
00084 static BOOL Array_TY_OK (TY_IDX array_ty);
00085
00086 static void Insert_Alloca(ST *array_st,
00087 INT16 ndims,
00088 INT64 esize,
00089 WN *dim_size_wn[],
00090 WN *block,
00091 WN *preamble);
00092
00093 static WN* Delete_Dist_Reshape_Pragmas (WN* pwn,
00094 WN* block);
00095
00096 static void DRA_Mangle_Entry(WN *entry_wn,
00097 INT16 num_formals,
00098 DRA_HASH_TABLE *dra_table,
00099 DST_ASSOC_INFO *assoc_info);
00100
00101 static void DRA_Mangle_Call_Site(WN *call_wn,
00102 OPERATOR call_oper,
00103 DRA_HASH_TABLE *dra_table);
00104
00105 static UINT DRA_Preprocess_Entry(WN *entry_wn,
00106 INT16 num_formals,
00107 DRA_HASH_TABLE *dra_table,
00108 BOOL *has_reshaped_formals);
00109
00110 static UINT DRA_Preprocess_Call_Site(WN *call_wn,
00111 INT16 num_args,
00112 DRA_HASH_TABLE *dra_table,
00113 BOOL *has_reshaped_args);
00114
00115 static char* DRA_Insert_Mangling_Sigs(char *orig_name,
00116 char mangled_buf[]);
00117
00118 static char* DRA_Encode_Parameter(ST *st,
00119 TY_IDX ty,
00120 char *buf,
00121 DRA_HASH_TABLE *dra_table);
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 static void
00142 DRA_Read_Pragmas_In_Block (WN *first, WN* block, WN *preamble,
00143 DRA_HASH_TABLE *dra_table)
00144 {
00145 WN *pwn = first;
00146
00147
00148
00149 while (pwn) {
00150
00151 if (WN_opcode(pwn) == OPC_REGION) {
00152
00153 DRA_Read_Pragmas_In_Block (WN_first(WN_region_body(pwn)), WN_region_body(pwn), preamble, dra_table);
00154 }
00155
00156 if (WN_opcode(pwn) == OPC_PRAGMA &&
00157 WN_pragma(pwn) == WN_PRAGMA_DISTRIBUTE_RESHAPE) {
00158
00159 ST *array_st = WN_st(pwn);
00160
00161 if (array_st == NULL || ST_is_not_used(array_st)) {
00162
00163
00164 pwn = Delete_Dist_Reshape_Pragmas(pwn, block);
00165 }
00166
00167 else {
00168
00169 TY_IDX array_ty = Get_Array_Type(array_st);
00170
00171 if (TY_kind(array_ty) != KIND_ARRAY) {
00172
00173
00174 ErrMsgSrcpos(EC_DRA_unsupported_type,
00175 WN_Get_Linenum(pwn),
00176 "DISTRIBUTE_RESHAPE",
00177 ST_name(array_st),
00178 "Cannot reshape non-arrays");
00179
00180 pwn = Delete_Dist_Reshape_Pragmas(pwn, block);
00181 }
00182
00183 else if (ST_is_equivalenced(array_st)) {
00184
00185
00186 ErrMsgSrcpos(EC_DRA_unsupported_type,
00187 WN_Get_Linenum(pwn),
00188 "DISTRIBUTE_RESHAPE",
00189 ST_name(array_st),
00190 "Cannot reshape equivalenced arrays");
00191
00192 pwn = Delete_Dist_Reshape_Pragmas(pwn, block);
00193 }
00194
00195 else if (ST_sclass(array_st) == SCLASS_DGLOBAL ||
00196 ST_is_initialized(array_st)) {
00197
00198
00199
00200 ErrMsgSrcpos(EC_DRA_unsupported_type,
00201 WN_Get_Linenum(pwn),
00202 "DISTRIBUTE_RESHAPE",
00203 ST_name(array_st),
00204 "Cannot reshape initialized data");
00205
00206 pwn = Delete_Dist_Reshape_Pragmas(pwn, block);
00207 }
00208
00209 else if (!Array_TY_OK (array_ty)) {
00210 ErrMsgSrcpos(EC_DRA_unsupported_type,
00211 WN_Get_Linenum(pwn),
00212 "DISTRIBUTE_RESHAPE",
00213 ST_name(array_st),
00214 "Cannot reshape assumed size arrays");
00215
00216 pwn = Delete_Dist_Reshape_Pragmas(pwn, block);
00217 }
00218
00219 else {
00220
00221 FmtAssert (ST_class(array_st) == CLASS_VAR,
00222 ("Distributed array is not a variable"));
00223
00224 DRA_INFO* dra = New_DRA(&pwn, array_st, array_ty, block, preamble);
00225
00226 if (dra != NULL) {
00227
00228
00229 dra_table->Enter(array_st, dra);
00230 }
00231 }
00232 }
00233 }
00234
00235 else {
00236 pwn = WN_next(pwn);
00237 }
00238 }
00239 }
00240
00241 void
00242 DRA_Read_Pragmas (WN* func_nd,
00243 DRA_HASH_TABLE *dra_table)
00244 {
00245 Set_Error_Phase("Processing DISTRIBUTE_RESHAPE pragmas");
00246
00247 WN *block = WN_func_body(func_nd);
00248 WN *preamble = Get_Preamble_End(func_nd);
00249
00250 DRA_Read_Pragmas_In_Block (preamble, block, preamble, dra_table);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 void
00270 DRA_Mangle_All(WN *func_wn,
00271 DRA_HASH_TABLE *dra_table,
00272 PU_Info *pu_info)
00273 {
00274
00275
00276 if (DRA_func_table == NULL) {
00277 DRA_func_table = CXX_NEW(NAME_ST_TABLE(31, &MEM_src_pool), &MEM_src_pool);
00278 }
00279
00280 DST_ASSOC_INFO* assoc_info = NULL;
00281 DST_IDX pu_idx = PU_Info_pu_dst(pu_info);
00282 if (!DST_IS_NULL(pu_idx)) {
00283 DST_INFO* info = DST_INFO_IDX_TO_PTR(pu_idx);
00284 DST_SUBPROGRAM* pu_attr =
00285 DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM);
00286 assoc_info = &(DST_SUBPROGRAM_def_st(pu_attr));
00287 }
00288
00289
00290
00291 DRA_Mangle_Entry(func_wn, WN_num_formals(func_wn), dra_table, assoc_info);
00292
00293
00294
00295 WN_ITER *wni;
00296 for (wni = WN_WALK_TreeIter(func_wn); wni; wni = WN_WALK_TreeNext(wni)) {
00297
00298 WN *stmt_wn = WN_ITER_wn(wni);
00299
00300 if (WN_opcode(stmt_wn) == OPC_ALTENTRY) {
00301 DST_ASSOC_INFO* assoc_info = NULL;
00302 DST_IDX dst_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(pu_idx));
00303 while (!DST_IS_NULL(dst_idx)) {
00304 DST_INFO* info = DST_INFO_IDX_TO_PTR(dst_idx);
00305 if (DST_INFO_tag(info) == DW_TAG_entry_point) {
00306 DST_ENTRY_POINT* attr =
00307 DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_ENTRY_POINT);
00308 if (DST_ASSOC_INFO_st_index(DST_ENTRY_POINT_st(attr)) ==
00309 ST_index(WN_st(stmt_wn))) {
00310 assoc_info = &(DST_ENTRY_POINT_st(attr));
00311 break;
00312 }
00313 }
00314 dst_idx = DST_INFO_sibling(info);
00315 }
00316
00317 DRA_Mangle_Entry(stmt_wn, WN_kid_count(stmt_wn), dra_table, assoc_info);
00318 }
00319
00320 else {
00321 OPERATOR stmt_oper = WN_operator(stmt_wn);
00322 if (stmt_oper == OPR_CALL || stmt_oper == OPR_ICALL) {
00323 DRA_Mangle_Call_Site(stmt_wn, stmt_oper, dra_table);
00324 }
00325 }
00326
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 WN*
00342 Get_Preamble_End(WN* entry_wn)
00343 {
00344 Is_True (WN_opcode(entry_wn) == OPC_FUNC_ENTRY ||
00345 WN_opcode(entry_wn) == OPC_ALTENTRY,
00346 ("Get_Preamble_End: Expected FUNC_ENTRY or ALTENTRY node"));
00347
00348 WN* wn;
00349 if (WN_opcode(entry_wn) == OPC_FUNC_ENTRY) {
00350 wn = WN_entry_first(entry_wn);
00351 }
00352 else {
00353 wn = WN_next(entry_wn);
00354 }
00355
00356 while (wn != NULL && (WN_opcode(wn) != OPC_PRAGMA ||
00357 WN_pragma(wn) != WN_PRAGMA_PREAMBLE_END)) {
00358 wn = WN_next(wn);
00359 }
00360
00361 Is_True (wn != NULL, ("Could not find the PREAMBLE_END pragma"));
00362
00363 return wn;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 ST*
00379 Find_Return_Registers(TYPE_ID type,
00380 PREG_NUM *rreg1,
00381 PREG_NUM *rreg2)
00382 {
00383 TYPE_ID mtype1;
00384 TYPE_ID mtype2;
00385
00386 if (WHIRL_Return_Info_On) {
00387
00388 RETURN_INFO return_info = Get_Return_Info (Be_Type_Tbl(type),
00389 Use_Simulated);
00390
00391 if (RETURN_INFO_count(return_info) <= 2) {
00392
00393 *rreg1 = RETURN_INFO_preg (return_info, 0);
00394 *rreg2 = RETURN_INFO_preg (return_info, 1);
00395 }
00396
00397 else {
00398
00399 Fail_FmtAssertion ("Find_Return_Registers: more than 2 return registers");
00400 return NULL;
00401 }
00402 }
00403
00404 else {
00405
00406 Get_Return_Mtypes(Be_Type_Tbl(type), Use_Simulated, &mtype1, &mtype2);
00407 Get_Return_Pregs(mtype1, mtype2, rreg1, rreg2);
00408 }
00409
00410 if (Preg_Offset_Is_Int(*rreg1)) {
00411 if (MTYPE_bit_size(type) == 32) {
00412 return Int32_Preg;
00413 } else {
00414 return Int64_Preg;
00415 }
00416 } else {
00417 if (MTYPE_bit_size(type) == 32) {
00418 return Float32_Preg;
00419 } else {
00420 return Float64_Preg;
00421 }
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 static DRA_INFO*
00449 New_DRA (WN** pwn_addr,
00450 ST *array_st,
00451 TY_IDX array_ty,
00452 WN *block,
00453 WN *preamble)
00454 {
00455 TY& ty = Ty_Table[array_ty];
00456 INT16 ndims = TY_AR_ndims(ty);
00457 INT64 esize = TY_size(TY_AR_etype(ty));
00458 DRA_INFO *dra = CXX_NEW(DRA_INFO(ndims, esize, DRA_name_pool_ptr),
00459 DRA_name_pool_ptr);
00460
00461 WN *pwn = *pwn_addr;
00462 WN **dim_size_wn = (WN**) alloca(ndims*sizeof(WN*));
00463 INT16 distr_dims = 0;
00464
00465 for (INT16 i = 0; i < ndims; i++) {
00466
00467
00468
00469 FmtAssert (WN_opcode(pwn) == OPC_PRAGMA,
00470 ("Distribute_Reshape_Pragma: expected a PRAGMA node\n"));
00471
00472 FmtAssert (WN_pragma(pwn) == WN_PRAGMA_DISTRIBUTE_RESHAPE,
00473 ("Distribute_Reshape_Pragma: unexpected PRAGMA type\n"));
00474
00475 switch (WN_pragma_distr_type(pwn)) {
00476
00477 case DISTRIBUTE_STAR:
00478 dra->Init (i, (DISTRIBUTE_TYPE) WN_pragma_distr_type(pwn));
00479 break;
00480
00481 case DISTRIBUTE_BLOCK:
00482 distr_dims++;
00483 dra->Init (i, (DISTRIBUTE_TYPE) WN_pragma_distr_type(pwn));
00484 break;
00485
00486 case DISTRIBUTE_CYCLIC_CONST:
00487 distr_dims++;
00488 dra->Init (i, (DISTRIBUTE_TYPE) WN_pragma_distr_type(pwn),
00489 (INT64) WN_pragma_arg2(pwn));
00490 break;
00491
00492 case DISTRIBUTE_CYCLIC_EXPR:
00493 distr_dims++;
00494 dra->Init (i, (DISTRIBUTE_TYPE) WN_pragma_distr_type(pwn));
00495
00496 pwn = WN_next(pwn);
00497
00498 FmtAssert (WN_opcode(pwn) == OPC_XPRAGMA,
00499 ("Distribute_Reshape_Pragma: expected an XPRAGMA node\n"));
00500
00501 FmtAssert (WN_pragma(pwn) == WN_PRAGMA_DISTRIBUTE_RESHAPE,
00502 ("Distribute_Reshape_Pragma: unexpected XPRAGMA type\n"));
00503
00504 break;
00505
00506 default:
00507 FmtAssert (FALSE,
00508 ("Distribute_Reshape_Pragma: strange distribute type\n"));
00509 break;
00510 }
00511
00512 pwn = WN_next(pwn);
00513 dim_size_wn[i] = WN_kid(pwn, 0);
00514
00515 FmtAssert (WN_opcode(pwn) == OPC_XPRAGMA,
00516 ("Distribute_Reshape_Pragma: expected an XPRAGMA node\n"));
00517
00518 FmtAssert (WN_pragma(pwn) == WN_PRAGMA_DISTRIBUTE_RESHAPE,
00519 ("Distribute_Reshape_Pragma: unexpected XPRAGMA type\n"));
00520
00521 pwn = WN_next(pwn);
00522 }
00523
00524
00525 if (distr_dims == 0) {
00526
00527 ErrMsgSrcpos(EC_DRA_all_stars,
00528 WN_Get_Linenum(*pwn_addr),
00529 ST_name(array_st));
00530
00531
00532
00533
00534 if (ST_sclass(array_st) == SCLASS_AUTO &&
00535 TY_kind(ST_type(array_st)) == KIND_POINTER) {
00536
00537 Insert_Alloca(array_st, ndims, esize, dim_size_wn, block, preamble);
00538 }
00539
00540 dra = NULL;
00541 pwn = Delete_Dist_Reshape_Pragmas (*pwn_addr, block);
00542
00543 }
00544
00545 *pwn_addr = pwn;
00546
00547 return dra;
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 static BOOL
00561 Array_TY_OK (TY_IDX array_ty)
00562 {
00563 const TY& ty = Ty_Table[array_ty];
00564
00565 Is_True (TY_kind(ty) == KIND_ARRAY,
00566 ("Array_TY_OK called on a non-array"));
00567
00568 INT16 ndims = TY_AR_ndims(ty);
00569
00570 Is_True (ndims > 0, ("Array_TY_OK: array has 0 dimensions?"));
00571
00572 for (INT16 i = 0; i < ndims; i++) {
00573
00574
00575 if ((!TY_AR_const_lbnd(ty, i)) &&
00576 (TY_AR_lbnd_val(ty, i) == 0)) {
00577 return FALSE;
00578 }
00579
00580 if ((!TY_AR_const_ubnd(ty, i)) &&
00581 (TY_AR_ubnd_val(ty, i) == 0)) {
00582 return FALSE;
00583 }
00584 }
00585
00586 return TRUE;
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 static void
00601 Insert_Alloca(ST *array_st,
00602 INT16 ndims,
00603 INT64 esize,
00604 WN *dim_size_wn[],
00605 WN *block,
00606 WN *preamble)
00607 {
00608 WN* size_wn = WN_Intconst(MTYPE_I8, esize);
00609 for (INT16 i = 0; i < ndims; i++) {
00610 size_wn = WN_Mpy(MTYPE_I8, size_wn, WN_CopyNode(dim_size_wn[i]));
00611 }
00612
00613 OPCODE call_op = OPCODE_make_op(OPR_INTRINSIC_CALL,
00614 Pointer_type,
00615 MTYPE_V);
00616 WN *call_wn = WN_Create(call_op, 1);
00617 WN_intrinsic(call_wn) =
00618 (Pointer_Size == 8) ? INTRN_U8I8ALLOCA : INTRN_U4I4ALLOCA;
00619
00620 WN* parm_wn = WN_CreateParm (Pointer_type,
00621 size_wn,
00622 Be_Type_Tbl(Pointer_type),
00623 WN_PARM_BY_REFERENCE);
00624 WN_kid0(call_wn) = parm_wn;
00625
00626
00627
00628
00629
00630 WN_INSERT_BlockBefore(block, preamble, call_wn);
00631
00632
00633
00634
00635 PREG_NUM rreg1, rreg2;
00636 ST* rst = Find_Return_Registers (Pointer_type, &rreg1, &rreg2);
00637 FmtAssert(rreg1 != 0 && rreg2 == 0, ("Bad pointer type ret regs"));
00638
00639 WN *ldid_wn =
00640 WN_CreateLdid (OPCODE_make_op(OPR_LDID, Pointer_type, Pointer_type),
00641 rreg1,
00642 rst,
00643 Be_Type_Tbl(Pointer_type));
00644
00645 WN *stid_wn =
00646 WN_CreateStid (OPCODE_make_op(OPR_STID, MTYPE_V, Pointer_type),
00647 0,
00648 array_st,
00649 ST_type(array_st),
00650 ldid_wn);
00651
00652
00653
00654
00655
00656 WN_INSERT_BlockBefore(block, preamble, stid_wn);
00657
00658 Set_ST_pt_to_unique_mem(array_st);
00659 Set_PU_has_alloca (Get_Current_PU ());
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 static WN*
00676 Delete_Dist_Reshape_Pragmas (WN* pwn,
00677 WN *block)
00678 {
00679 FmtAssert (WN_opcode(pwn) == OPC_PRAGMA &&
00680 WN_pragma(pwn) == WN_PRAGMA_DISTRIBUTE_RESHAPE,
00681 ("Delete_Dist_Reshape_Pragma: Wrong opcode and/or pragma\n"));
00682
00683 WN *current = pwn;
00684 WN *next;
00685 ST *st = WN_st(current);
00686
00687 while (current) {
00688
00689
00690
00691 next = WN_next(current);
00692
00693
00694
00695 WN_DELETE_FromBlock (block, current);
00696
00697
00698
00699
00700 current = next;
00701
00702
00703
00704 if ((WN_opcode(current) != OPC_PRAGMA &&
00705 WN_opcode(current) != OPC_XPRAGMA) ||
00706 WN_pragma(current) != WN_PRAGMA_DISTRIBUTE_RESHAPE ||
00707 WN_st(current) != st) {
00708 return current;
00709 }
00710 }
00711
00712 return NULL;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 static void
00725 Change_ST_Of_Current_PU(ST *new_entry_st)
00726 {
00727
00728
00729
00730 Current_PU_Info->proc_sym = ST_st_idx(new_entry_st);
00731 Scope_tab[CURRENT_SYMTAB].st = new_entry_st;
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 static void
00744 DRA_Mangle_Entry(WN* entry_wn,
00745 INT16 num_formals,
00746 DRA_HASH_TABLE* dra_table,
00747 DST_ASSOC_INFO* assoc_info)
00748 {
00749 BOOL has_reshaped_formals = FALSE;
00750
00751 UINT bufsize = DRA_Preprocess_Entry(entry_wn,
00752 num_formals,
00753 dra_table,
00754 &has_reshaped_formals);
00755
00756 if (has_reshaped_formals) {
00757
00758
00759
00760 char *mangled_buf = (char *) alloca(bufsize);
00761 char *entry_name = ST_name(WN_st(entry_wn));
00762 char *mangled_ptr = DRA_Insert_Mangling_Sigs(entry_name, mangled_buf);
00763
00764
00765
00766 for (INT16 formal = 0; formal < num_formals; ++formal) {
00767
00768 ST *formal_st = WN_st(WN_formal(entry_wn, formal));
00769 TY_IDX formal_ty = Get_Array_Type(formal_st);
00770
00771 mangled_ptr = DRA_Encode_Parameter(formal_st,
00772 formal_ty,
00773 mangled_ptr,
00774 dra_table);
00775 *mangled_ptr++ = DRA_ARG_SEPARATOR;
00776 }
00777
00778 *mangled_ptr = '\0';
00779
00780
00781
00782
00783 ST *old_st = WN_st(entry_wn);
00784 ST *entry_st = old_st;
00785
00786
00787
00788 MANGLED_FUNC *entry_desc = DRA_func_table->Find(Save_Str(mangled_buf));
00789
00790 if (entry_desc == NULL) {
00791
00792 if (strcmp(entry_name, mangled_buf) != 0) {
00793
00794
00795
00796 entry_st = Copy_ST(entry_st, TRUE);
00797 WN_st_idx(entry_wn) = ST_st_idx(entry_st);
00798 Set_ST_name(entry_st, Save_Str(mangled_buf));
00799 Clear_ST_is_not_used(entry_st);
00800 }
00801
00802
00803
00804 entry_desc = CXX_NEW(MANGLED_FUNC, &MEM_src_pool);
00805 entry_desc->st = entry_st;
00806 entry_desc->is_clone = FALSE;
00807 entry_desc->is_called = FALSE;
00808 DRA_func_table->Enter(ST_name_idx(entry_st), entry_desc);
00809 }
00810
00811 else {
00812 entry_st = entry_desc->st;
00813 WN_st_idx (entry_wn) = ST_st_idx (entry_st);
00814 Set_ST_sclass (entry_st, SCLASS_TEXT);
00815
00816
00817 if (Run_cg) {
00818 Set_ST_base (entry_st, ST_base(old_st));
00819 }
00820 }
00821
00822
00823
00824 if (assoc_info != NULL) {
00825 pDST_ASSOC_INFO_st_idx(assoc_info) = ST_st_idx(entry_st);
00826 }
00827
00828
00829
00830 if (entry_st != old_st) {
00831 Change_ST_Of_Current_PU(entry_st);
00832 Set_ST_sclass (old_st, SCLASS_EXTERN);
00833 if (!PU_has_non_mangled_call (Pu_Table[ST_pu (old_st)]))
00834 Set_ST_is_not_used (old_st);
00835 }
00836 }
00837 else {
00838 Set_PU_has_non_mangled_call(Pu_Table[ST_pu(WN_st(entry_wn))]);
00839 Clear_ST_is_not_used(WN_st(entry_wn));
00840 }
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854 static void
00855 DRA_Mangle_Call_Site(WN *call_wn,
00856 OPERATOR call_oper,
00857 DRA_HASH_TABLE *dra_table)
00858 {
00859
00860
00861 if (call_oper == OPR_CALL &&
00862 strncmp(ST_name(WN_st(call_wn)), "dsm_", 4) == 0) {
00863 return;
00864 }
00865
00866
00867
00868 if (call_oper == OPR_CALL &&
00869 (strcmp (ST_name(WN_st(call_wn)), "printf") == 0 ||
00870 strcmp (ST_name(WN_st(call_wn)), "fprintf") == 0 ||
00871 strcmp (ST_name(WN_st(call_wn)), "sprintf") == 0 ||
00872 strcmp (ST_name(WN_st(call_wn)), "vprintf") == 0 ||
00873 strcmp (ST_name(WN_st(call_wn)), "vfprintf") == 0 ||
00874 strcmp (ST_name(WN_st(call_wn)), "vsprintf") == 0 ||
00875 strcmp (ST_name(WN_st(call_wn)), "scanf") == 0 ||
00876 strcmp (ST_name(WN_st(call_wn)), "sscanf") == 0 ||
00877 strcmp (ST_name(WN_st(call_wn)), "fscanf") == 0)) {
00878 return;
00879 }
00880
00881 BOOL has_reshaped_args = FALSE;
00882 INT16 num_args = WN_num_actuals(call_wn);
00883
00884 UINT bufsize = DRA_Preprocess_Call_Site(call_wn,
00885 num_args,
00886 dra_table,
00887 &has_reshaped_args);
00888
00889 if (has_reshaped_args) {
00890
00891
00892
00893
00894 if (call_oper == OPR_ICALL) {
00895 ErrMsgSrcpos(EC_DRA_indirect_call, WN_Get_Linenum(call_wn));
00896 return;
00897 }
00898
00899
00900
00901 char *mangled_buf = (char *) alloca(bufsize);
00902 char *call_name = ST_name(WN_st(call_wn));
00903 char *mangled_ptr = DRA_Insert_Mangling_Sigs(call_name, mangled_buf);
00904
00905
00906
00907 for (INT16 arg = 0; arg < num_args; ++arg) {
00908
00909
00910
00911 WN *arg_wn = WN_kid(WN_actual(call_wn,arg), 0);
00912
00913 if (WN_operator(arg_wn) == OPR_LDA ||
00914 WN_operator(arg_wn) == OPR_LDID) {
00915
00916 ST *arg_st = WN_st(arg_wn);
00917 TY_IDX arg_ty = Get_Array_Type(arg_st);
00918
00919 mangled_ptr = DRA_Encode_Parameter(arg_st,
00920 arg_ty,
00921 mangled_ptr,
00922 dra_table);
00923 }
00924 else {
00925
00926
00927 *mangled_ptr++ = '0';
00928 }
00929 *mangled_ptr++ = DRA_ARG_SEPARATOR;
00930 }
00931 *mangled_ptr = '\0';
00932
00933
00934
00935
00936 ST *old_st = WN_st(call_wn);
00937
00938
00939
00940 MANGLED_FUNC *call_desc = DRA_func_table->Find(Save_Str(mangled_buf));
00941
00942 if (call_desc == NULL) {
00943
00944
00945
00946 PU_IDX new_pu_idx;
00947 PU& new_pu = New_PU (new_pu_idx);
00948 Pu_Table[new_pu_idx] = Pu_Table[ST_pu(old_st)];
00949 Set_PU_no_inline (new_pu);
00950
00951 ST *new_st = Copy_ST(old_st);
00952 WN_st_idx (call_wn) = ST_st_idx (new_st);
00953 Clear_ST_is_not_used (new_st);
00954
00955
00956
00957 Set_ST_pu (new_st, new_pu_idx);
00958
00959
00960
00961 Set_ST_name (new_st, Save_Str(mangled_buf));
00962
00963
00964
00965 Set_ST_sclass (new_st, SCLASS_EXTERN);
00966
00967
00968
00969 Set_ST_base (new_st, new_st);
00970 Set_ST_ofst (new_st, 0);
00971
00972
00973
00974 call_desc = CXX_NEW(MANGLED_FUNC, &MEM_src_pool);
00975 call_desc->st = new_st;
00976 call_desc->is_called = TRUE;
00977 DRA_func_table->Enter(ST_name_idx(new_st), call_desc);
00978 } else {
00979
00980
00981 WN_st_idx (call_wn) = ST_st_idx (call_desc->st);
00982 call_desc->is_called = TRUE;
00983 }
00984
00985
00986
00987 if (!PU_has_non_mangled_call (Pu_Table[ST_pu (old_st)]))
00988 Set_ST_is_not_used (old_st);
00989 }
00990
00991 else {
00992
00993
00994 if (call_oper == OPR_CALL) {
00995 ST* st = WN_st (call_wn);
00996 Set_PU_has_non_mangled_call (Pu_Table[ST_pu (st)]);
00997 Clear_ST_is_not_used (st);
00998 }
00999 }
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 static UINT
01015 DRA_Preprocess_Entry(WN *entry_wn,
01016 INT16 num_formals,
01017 DRA_HASH_TABLE *dra_table,
01018 BOOL *has_reshaped_formals)
01019 {
01020 UINT bufsize = strlen(ST_name(WN_st(entry_wn))) + 2*DRA_MANGLE_SIG_LEN + 1;
01021
01022 for (INT16 formal = 0; formal < num_formals; ++formal) {
01023
01024 ST *formal_st = WN_st(WN_formal(entry_wn, formal));
01025 TY_IDX formal_ty = Get_Array_Type(formal_st);
01026
01027 if (TY_kind(formal_ty) != KIND_ARRAY) {
01028 bufsize += 2;
01029 }
01030 else {
01031 DRA_INFO *dra = dra_table->Find(formal_st);
01032 if (dra == NULL) {
01033 bufsize += 2;
01034 }
01035 else {
01036 *has_reshaped_formals = TRUE;
01037
01038
01039
01040
01041 bufsize += 28 + 22*TY_AR_ndims(Ty_Table[formal_ty]);
01042 }
01043 }
01044 }
01045
01046 return bufsize;
01047 }
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 static UINT
01062 DRA_Preprocess_Call_Site(WN *call_wn,
01063 INT16 num_args,
01064 DRA_HASH_TABLE *dra_table,
01065 BOOL *has_reshaped_args)
01066 {
01067 UINT bufsize = 0;
01068 if (WN_operator(call_wn) == OPR_CALL) {
01069 bufsize = strlen(ST_name(WN_st(call_wn))) + 2*DRA_MANGLE_SIG_LEN + 1;
01070 }
01071
01072 for (INT16 arg = 0; arg < num_args; ++arg) {
01073
01074
01075
01076 WN *parm_wn = WN_actual(call_wn, arg);
01077 WN *arg_wn = WN_kid(parm_wn, 0);
01078
01079 if (WN_operator(arg_wn) == OPR_LDA ||
01080 WN_operator(arg_wn) == OPR_LDID) {
01081
01082 ST *arg_st = WN_st(arg_wn);
01083 TY_IDX arg_ty = Get_Array_Type(arg_st);
01084
01085 if (TY_kind(arg_ty) != KIND_ARRAY) {
01086 bufsize += 2;
01087 }
01088 else {
01089 DRA_INFO *dra = dra_table->Find(arg_st);
01090 if (dra == NULL) {
01091 bufsize += 2;
01092 }
01093 else {
01094 *has_reshaped_args = TRUE;
01095
01096
01097
01098
01099 bufsize += 28 + 22*TY_AR_ndims(Ty_Table[arg_ty]);
01100 }
01101 }
01102 }
01103 else {
01104 bufsize += 2;
01105 }
01106 }
01107
01108 return bufsize;
01109 }
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123 static char*
01124 DRA_Insert_Mangling_Sigs(char *orig_name,
01125 char mangled_buf[])
01126 {
01127
01128 if (strncmp(orig_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN)) {
01129
01130
01131 (void) strcpy(mangled_buf, DRA_MANGLE_SIG);
01132 (void) strcpy(mangled_buf + DRA_MANGLE_SIG_LEN, orig_name);
01133 (void) strcpy(mangled_buf + DRA_MANGLE_SIG_LEN + strlen(orig_name),
01134 DRA_MANGLE_SIG);
01135 }
01136 else {
01137
01138
01139 INT name_len = strstr(orig_name+1, DRA_MANGLE_SIG)
01140 + DRA_MANGLE_SIG_LEN - orig_name;
01141 (void) strncpy(mangled_buf, orig_name, name_len);
01142 mangled_buf[name_len] = '\0';
01143 }
01144
01145 return (mangled_buf + strlen(mangled_buf));
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 static char*
01162 DRA_Encode_Parameter(ST *st,
01163 TY_IDX ty_idx,
01164 char *buf,
01165 DRA_HASH_TABLE *dra_table)
01166 {
01167 TY& ty = Ty_Table[ty_idx];
01168
01169
01170 if (TY_kind(ty) != KIND_ARRAY) {
01171 *buf++ = '0';
01172 return buf;
01173 }
01174
01175 DRA_INFO *dra = dra_table->Find(st);
01176
01177
01178
01179 if (dra == NULL) {
01180 *buf++ = '0';
01181 return buf;
01182 }
01183
01184
01185
01186 INT16 ndims = ARB_dimension (TY_arb(ty));
01187 UINT64 size = TY_size (TY_etype(ty));
01188 buf += sprintf(buf, "%d%c", ndims, DRA_NDIMS_END);
01189 buf += sprintf(buf, "%lld%c", size, DRA_ESIZE_END);
01190
01191 for (INT16 dim = 0; dim < ndims; ++dim) {
01192
01193 switch (dra->Distr_Type(dim)) {
01194
01195 case DISTRIBUTE_STAR:
01196 *buf++ = DRA_STAR_CODE;
01197 break;
01198
01199 case DISTRIBUTE_BLOCK:
01200 *buf++ = DRA_BLOCK_CODE;
01201 break;
01202
01203 case DISTRIBUTE_CYCLIC_CONST:
01204 *buf++ = DRA_CYCLIC_CODE;
01205 buf += sprintf(buf, "%lld", dra->Chunk_Const_Val(dim));
01206 break;
01207
01208 case DISTRIBUTE_CYCLIC_EXPR:
01209 *buf++ = DRA_CYCLIC_CODE;
01210 break;
01211 }
01212 }
01213
01214 return buf;
01215 }