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 #define ONST(x, y) (y)
00056
00057 #define __STDC_LIMIT_MACROS
00058 #include <alloca.h>
00059 #include <unistd.h>
00060 #include <stdint.h>
00061
00062 #include "pu_info.h"
00063
00064 #include "defs.h"
00065 #include "config_asm.h"
00066 #include "wn.h"
00067 #include "wn_map.h"
00068 #include "wn_util.h"
00069 #include "symtab.h"
00070 #include "strtab.h"
00071 #include "mempool.h"
00072 #include "cxx_memory.h"
00073 #include "erbe.h"
00074 #include "errors.h"
00075 #include "dwarf_DST_mem.h"
00076 #include "clone.h"
00077 #include "clone_DST_utils.h"
00078 #include "dra_demangle.h"
00079
00080 #include "dra_internal.h"
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 static BOOL DRA_Clone_Initialize(void);
00091
00092 static BOOL DRA_Process_Requests(char *tir_names);
00093
00094 static BOOL DRA_Parse_Clone_Name(char *clone_name);
00095
00096 static void DRA_Clone_Instantiate(PU_Info *orig_pu,
00097 BOOL pu_has_feedback,
00098 STRING_LIST *tir_list,
00099 DRA_HASH_TABLE *dra_table);
00100
00101 static char* DRA_New_Clone_Sig(WN *pu_wn,
00102 char *clone_name,
00103 DRA_HASH_TABLE *dra_table);
00104
00105 static void DRA_Add_Clone (PU_Info *orig_pu,
00106 MEM_POOL *mem_pool,
00107 STR_IDX clone_name,
00108 char *arg_sig,
00109 BOOL pu_has_feedback);
00110
00111 static void DRA_Insert_Pragmas(WN *pu_wn,
00112 char *arg_sig);
00113
00114 static void DRA_Process_Commons(DRA_HASH_TABLE *dra_table,
00115 DRA_COMMON_HASH_TABLE*);
00116
00117 static void DRA_Collect_Commons(WN *pu,
00118 DRA_COMMON_HASH_TABLE *dra_common_ht);
00119
00120 static void DRA_Process_Globals(DRA_HASH_TABLE *dra_table);
00121
00122 static BOOL DRA_Info_Matches_Encoding(DRA_INFO *dra,
00123 char *arg_sig);
00124
00125
00126
00127
00128
00129
00130
00131 BOOL Run_Dsm_Cloner = FALSE;
00132
00133 BOOL Run_Dsm_Common_Check = FALSE;
00134
00135 BOOL Run_Dsm_Check = FALSE;
00136
00137 NAME_ST_TABLE *DRA_func_table = NULL;
00138
00139 MEM_POOL DRA_name_pool, *DRA_name_pool_ptr = NULL;
00140
00141 DRA_GLOBAL_HASH_TABLE* dra_global = NULL;
00142
00143
00144
00145
00146
00147
00148
00149 static STRING_LIST_TABLE *DRA_clone_table;
00150
00151 static MEM_POOL DRA_clone_pool, *DRA_clone_pool_ptr = NULL;
00152
00153 static MEM_POOL DRA_check_pool, *DRA_check_pool_ptr = NULL;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 extern TY_IDX Get_Original_Type (ST* st) {
00174
00175 TY_IDX ty;
00176
00177 if (ST_class(st) != CLASS_VAR) return ST_type(st);
00178
00179 if (ONST(ST_is_global(st),ST_level(st) == GLOBAL_SYMTAB) &&
00180 ST_is_reshaped(st)) {
00181
00182 DRA_GLOBAL_INFO* dgi = dra_global->Find(st);
00183
00184 if (dgi) {
00185
00186 ty = dgi->Get_TY();
00187 }
00188 else {
00189
00190 ty = ST_type(st);
00191 DRA_GLOBAL_INFO* dgi = CXX_NEW (DRA_GLOBAL_INFO(ty), Malloc_Mem_Pool);
00192 dra_global->Enter (st, dgi);
00193 }
00194 }
00195 else {
00196 ty = ST_type(st);
00197 }
00198 return ty;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 extern TY_IDX Get_Array_Type (ST* st) {
00210
00211 TY_IDX ty;
00212
00213 ty = Get_Original_Type (st);
00214
00215 if (TY_kind(ty) == KIND_POINTER &&
00216 (ST_sclass(st) == SCLASS_FORMAL ||
00217 ST_sclass(st) == SCLASS_AUTO ||
00218 (ONST(ST_sclass(st)==SCLASS_BASED, ST_base_idx(st)==ST_st_idx(st)) &&
00219 ST_sclass(ST_base(st)) == SCLASS_AUTO))) {
00220 ty = TY_pointed(ty);
00221 }
00222
00223 return ty;
00224 }
00225
00226
00227 extern "C" void
00228 DRA_Initialize(void)
00229 {
00230 DRA_Open_And_Map_File();
00231
00232 if (Run_Dsm_Cloner && DRA_Clone_Initialize()) {
00233 Set_FILE_INFO_needs_lno (File_info);
00234 }
00235
00236 if (Run_Dsm_Common_Check) {
00237 MEM_POOL_Initialize (&DRA_check_pool, "DRA Common Check", TRUE);
00238 DRA_check_pool_ptr = &DRA_check_pool;
00239 DRA_Set_Write_Location();
00240 }
00241
00242 if (Run_Dsm_Check) {
00243 DRA_EC_Declare_Types();
00244 }
00245
00246
00247 dra_global = CXX_NEW (DRA_GLOBAL_HASH_TABLE(20, Malloc_Mem_Pool),
00248 Malloc_Mem_Pool);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 extern "C" void
00263 DRA_Finalize (void)
00264 {
00265 ST *st;
00266
00267
00268
00269 {
00270 HASH_TABLE_ITER<ST*, DRA_GLOBAL_INFO*> iter (dra_global);
00271 ST* st;
00272 DRA_GLOBAL_INFO* dgi;
00273 while (iter.Step (&st, &dgi)) {
00274 CXX_DELETE (dgi, Malloc_Mem_Pool);
00275 }
00276 CXX_DELETE (dra_global, Malloc_Mem_Pool);
00277 dra_global = NULL;
00278 }
00279
00280
00281
00282 INT i;
00283 FOREACH_SYMBOL (GLOBAL_SYMTAB, st, i) {
00284 if (ST_is_not_used(st) &&
00285 ST_class(st) == CLASS_FUNC &&
00286 ST_sclass(st) == SCLASS_EXTERN &&
00287 !PU_has_non_mangled_call(Pu_Table[ST_pu(*st)])) {
00288 Set_ST_export(st, EXPORT_LOCAL);
00289 Set_ST_sclass(st, SCLASS_TEXT);
00290 }
00291 }
00292
00293
00294
00295
00296 if (DRA_func_table != NULL) {
00297
00298 NAME_ST_TABLE_ITER iter(DRA_func_table);
00299 STR_IDX func_name;
00300 MANGLED_FUNC *func_desc;
00301
00302 while (iter.Step(&func_name, &func_desc)) {
00303
00304 if (func_desc->is_clone && func_desc->is_called) {
00305 ST* aux_st = New_ST (GLOBAL_SYMTAB);
00306 ST_Init (aux_st,
00307 func_name,
00308 CLASS_NAME,
00309 SCLASS_UNKNOWN,
00310 EXPORT_LOCAL,
00311 (TY_IDX) NULL);
00312 Set_ST_is_not_used(aux_st);
00313 Set_ST_emit_symbol(aux_st);
00314 }
00315 }
00316 }
00317
00318 if (DRA_clone_pool_ptr != NULL) {
00319 MEM_POOL_Pop (DRA_clone_pool_ptr);
00320 MEM_POOL_Delete (DRA_clone_pool_ptr);
00321 DRA_clone_pool_ptr = NULL;
00322 }
00323
00324 if (DRA_check_pool_ptr != NULL) {
00325 MEM_POOL_Delete (DRA_check_pool_ptr);
00326 DRA_check_pool_ptr = NULL;
00327 }
00328
00329 DRA_Close_File();
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 extern "C" void
00345 DRA_Processing(PU_Info *pu_info,
00346 WN* pu,
00347 BOOL pu_has_feedback)
00348 {
00349 STRING_LIST *clone_requests = NULL;
00350 DRA_HASH_TABLE *dra_table = NULL;
00351
00352 Set_Error_Phase("DRA Processing");
00353
00354 if (Run_Dsm_Cloner) {
00355 clone_requests = DRA_clone_table->Find(ST_name_idx(WN_st(pu)));
00356 }
00357
00358 if (clone_requests != NULL ||
00359 Run_Dsm_Common_Check ||
00360 ONST(SYMTAB_mp_needs_lno(Current_Symtab),
00361 PU_mp_needs_lno (Get_Current_PU()))) {
00362
00363
00364
00365 DRA_name_pool_ptr = &DRA_name_pool;
00366 MEM_POOL_Initialize (DRA_name_pool_ptr, "DRA Names", FALSE);
00367 MEM_POOL_Push (DRA_name_pool_ptr);
00368
00369
00370
00371 dra_table = CXX_NEW(DRA_HASH_TABLE(31, DRA_name_pool_ptr),
00372 DRA_name_pool_ptr);
00373
00374 DRA_Read_Pragmas(pu, dra_table);
00375 }
00376
00377 if (clone_requests != NULL) {
00378 DRA_Clone_Instantiate(pu_info, pu_has_feedback, clone_requests, dra_table);
00379 }
00380
00381 if (Run_Dsm_Common_Check) {
00382 MEM_POOL_Push (DRA_check_pool_ptr);
00383 DRA_COMMON_HASH_TABLE
00384 *dra_common_ht = CXX_NEW (DRA_COMMON_HASH_TABLE(20, DRA_check_pool_ptr),
00385 DRA_check_pool_ptr);
00386
00387 DRA_Collect_Commons(pu, dra_common_ht);
00388 DRA_Process_Commons(dra_table, dra_common_ht);
00389
00390 CXX_DELETE (dra_common_ht, DRA_check_pool_ptr);
00391 MEM_POOL_Pop (DRA_check_pool_ptr);
00392
00393
00394
00395 DRA_Process_Globals(dra_table);
00396 }
00397
00398 if (dra_table->Num_Entries() > 0) {
00399 DRA_Mangle_All(pu, dra_table, pu_info);
00400 Set_PU_no_inline(Pu_Table[ST_pu(WN_st(pu))]);
00401 }
00402 else {
00403 Set_PU_has_non_mangled_call(Pu_Table[ST_pu(WN_st(pu))]);
00404 Clear_ST_is_not_used(WN_st(pu));
00405 }
00406
00407 if (Run_Dsm_Check) {
00408 DRA_EC_Array_Portion_Parms(pu, pu);
00409
00410 if (ONST(SYMTAB_has_altentry(Current_Symtab),
00411 PU_has_altentry (Get_Current_PU()))) {
00412
00413
00414 WN_ITER *wni;
00415 for (wni = WN_WALK_TreeIter(pu); wni; wni = WN_WALK_TreeNext(wni)) {
00416 if (WN_opcode(WN_ITER_wn(wni)) == OPC_ALTENTRY) {
00417 DRA_EC_Array_Portion_Parms(pu, WN_ITER_wn(wni));
00418 }
00419 }
00420 }
00421 }
00422
00423
00424
00425 if (DRA_name_pool_ptr != NULL) {
00426 MEM_POOL_Pop (DRA_name_pool_ptr);
00427 MEM_POOL_Delete (DRA_name_pool_ptr);
00428 DRA_name_pool_ptr = NULL;
00429 }
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 static BOOL
00452 DRA_Clone_Initialize(void)
00453 {
00454
00455
00456
00457 MEM_POOL_Initialize (&DRA_clone_pool, "DRA Cloning", TRUE);
00458 DRA_clone_pool_ptr = &DRA_clone_pool;
00459 MEM_POOL_Push (DRA_clone_pool_ptr);
00460
00461
00462
00463 char *tir_names = strstr(DRA_file_mmap, DRA_FILE_SEPARATOR)
00464 + strlen(DRA_FILE_SEPARATOR);
00465
00466
00467
00468
00469 DRA_clone_table = CXX_NEW(STRING_LIST_TABLE(31, DRA_clone_pool_ptr),
00470 DRA_clone_pool_ptr);
00471
00472
00473
00474 BOOL needs_cloning = DRA_Process_Requests(tir_names);
00475
00476
00477
00478 if (DRA_func_table == NULL) {
00479 DRA_func_table = CXX_NEW(NAME_ST_TABLE(31, &MEM_src_pool),
00480 &MEM_src_pool);
00481 }
00482
00483 DRA_Mem_Unmap_File();
00484
00485 return needs_cloning;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 static BOOL
00503 DRA_Process_Requests(char *tir_name)
00504 {
00505 BOOL needs_cloning = FALSE;
00506
00507
00508
00509 char *end_tir_names = strstr(tir_name, DRA_FILE_SEPARATOR);
00510 if (end_tir_names != NULL) {
00511 *end_tir_names = '\0';
00512 }
00513
00514
00515 char *end_of_line;
00516 for ( ; *tir_name; *end_of_line = '\n', tir_name = end_of_line+1) {
00517
00518
00519
00520 if ((end_of_line = strchr(tir_name, '\n')) == NULL) {
00521 break;
00522 }
00523
00524
00525
00526 *end_of_line = '\0';
00527
00528
00529
00530 if (!DRA_Parse_Clone_Name(tir_name)) {
00531 (void) unlink(DRA_file_name);
00532 ErrMsg(EC_DRA_rii_file_format, DRA_file_name);
00533 return FALSE;
00534 }
00535
00536 char *orig_name = tir_name + DRA_MANGLE_SIG_LEN;
00537 char *postfix_sig = strstr(orig_name, DRA_MANGLE_SIG);
00538
00539 STR_IDX save_tir_name = Save_Str(tir_name);
00540
00541 *postfix_sig = '\0';
00542
00543 STR_IDX save_orig_name = Save_Str(orig_name);
00544
00545
00546
00547 *postfix_sig = DRA_MANGLE_SIG[0];
00548
00549
00550
00551
00552 STRING_LIST *tir_list = DRA_clone_table->Find(save_orig_name);
00553
00554
00555
00556 if (tir_list == NULL) {
00557 tir_list = CXX_NEW(STRING_LIST(), DRA_clone_pool_ptr);
00558 DRA_clone_table->Enter(save_orig_name, tir_list);
00559 }
00560
00561
00562
00563 STRING_NODE *tir_node =
00564 CXX_NEW(STRING_NODE(save_tir_name), DRA_clone_pool_ptr);
00565 tir_list->Append(tir_node);
00566
00567 needs_cloning = TRUE;
00568 }
00569
00570
00571
00572
00573 if (end_tir_names != NULL) {
00574 *end_tir_names = DRA_FILE_SEPARATOR[0];
00575 }
00576
00577 return needs_cloning;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 static BOOL
00593 DRA_Parse_Clone_Name(char *clone_name)
00594 {
00595
00596
00597 if (strncmp(clone_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN) != 0)
00598 return FALSE;
00599
00600 char *arg_sig = strstr(clone_name + DRA_MANGLE_SIG_LEN, DRA_MANGLE_SIG);
00601
00602
00603
00604 if (arg_sig == NULL || *(arg_sig += DRA_MANGLE_SIG_LEN) == 0)
00605 return FALSE;
00606
00607
00608
00609
00610 for ( ; *arg_sig; ) {
00611
00612 char *current;
00613
00614
00615
00616
00617 INT64 num_dims = (INT64) strtol(arg_sig, ¤t, 10);
00618
00619 if (current == arg_sig)
00620 return FALSE;
00621
00622 if (num_dims == 0) {
00623 if (*current++ != DRA_ARG_SEPARATOR)
00624 return FALSE;
00625 else {
00626 arg_sig = current;
00627 continue;
00628 }
00629 }
00630
00631 if (num_dims < 0 || num_dims > INT16_MAX)
00632 return FALSE;
00633
00634
00635
00636
00637 if (*current++ != DRA_NDIMS_END)
00638 return FALSE;
00639
00640 arg_sig = current;
00641
00642 INT64 esize = (INT64) strtol(arg_sig, ¤t, 10);
00643
00644 if (current == arg_sig || esize <= 0 || *current++ != DRA_ESIZE_END)
00645 return FALSE;
00646
00647 arg_sig = current;
00648
00649
00650
00651
00652 for (INT16 dim = 0; dim < num_dims; dim++) {
00653
00654 if (*arg_sig == DRA_BLOCK_CODE || *arg_sig == DRA_STAR_CODE) {
00655 arg_sig++;
00656 continue;
00657 }
00658
00659 else if (*arg_sig == DRA_CYCLIC_CODE) {
00660
00661 if (arg_sig[1] == DRA_BLOCK_CODE ||
00662 arg_sig[1] == DRA_STAR_CODE ||
00663 arg_sig[1] == DRA_CYCLIC_CODE ||
00664 (arg_sig[1] == DRA_ARG_SEPARATOR && dim == num_dims-1)) {
00665 arg_sig++;
00666 continue;
00667 }
00668
00669 arg_sig++;
00670
00671 INT64 chunk = (INT64) strtol(arg_sig, ¤t, 10);
00672
00673 if (current == arg_sig || chunk <= 0)
00674 return FALSE;
00675
00676 arg_sig = current;
00677 }
00678
00679 else
00680 return FALSE;
00681 }
00682
00683 if (*arg_sig++ != DRA_ARG_SEPARATOR)
00684 return FALSE;
00685 }
00686
00687 return TRUE;
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 static void
00703 DRA_Clone_Instantiate(PU_Info *orig_pu,
00704 BOOL pu_has_feedback,
00705 STRING_LIST *tir_list,
00706 DRA_HASH_TABLE *dra_table)
00707 {
00708
00709
00710 if (ONST(SYMTAB_has_altentry(Current_Symtab),
00711 PU_has_altentry(Get_Current_PU()))) {
00712 ErrMsgSrcpos(EC_DRA_clone_altentry,
00713 WN_Get_Linenum(PU_Info_tree_ptr(orig_pu)));
00714 return;
00715 }
00716
00717
00718
00719 STRING_ITER tir_iter(tir_list);
00720 STRING_NODE *n;
00721
00722 for (n = tir_iter.First(); !tir_iter.Is_Empty(); n = tir_iter.Next()) {
00723
00724 STR_IDX clone_name = n->String();
00725
00726
00727
00728
00729 char *arg_sig = DRA_New_Clone_Sig(PU_Info_tree_ptr(orig_pu),
00730 Index_To_Str(clone_name),
00731 dra_table);
00732
00733
00734
00735 if (arg_sig != NULL) {
00736 DRA_Add_Clone(orig_pu,
00737 DRA_clone_pool_ptr,
00738 clone_name,
00739 arg_sig,
00740 pu_has_feedback);
00741 }
00742 }
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759 static char*
00760 DRA_New_Clone_Sig(WN *pu_wn,
00761 char *clone_name,
00762 DRA_HASH_TABLE *dra_table)
00763 {
00764 Set_Error_Phase("Instantiating DRA Clones");
00765
00766 FmtAssert(strncmp(clone_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN) == 0,
00767 ("The name of a DRA clone does not have DRA_MANGLE_SIG prefix"));
00768
00769 char *arg_sig = strstr(clone_name + DRA_MANGLE_SIG_LEN, DRA_MANGLE_SIG);
00770
00771 FmtAssert(arg_sig != NULL,
00772 ("The name of a DRA clone does not have DRA_MANGLE_SIG postfix"));
00773
00774 arg_sig += DRA_MANGLE_SIG_LEN;
00775
00776 char *buf = CXX_NEW_ARRAY(char, strlen(arg_sig)+1, DRA_name_pool_ptr);
00777 char *bufptr = buf;
00778
00779 char *dim_sig;
00780
00781
00782 INT16 arg_pos;
00783 for ( arg_pos = 0; *arg_sig; arg_sig++, arg_pos++ ) {
00784
00785 ST *arg_st = WN_st(WN_kid(pu_wn, arg_pos));
00786
00787 if (arg_st == NULL) {
00788
00789
00790 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00791 WN_Get_Linenum(pu_wn),
00792 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00793 "cannot be satisfied -- too many arguments passed or types mismatch");
00794
00795
00796 return NULL;
00797 }
00798
00799
00800
00801 TY_IDX arg_ty = Get_Array_Type(arg_st);
00802 DRA_INFO *dra = dra_table->Find(arg_st);
00803 INT16 num_dims = (INT16) strtol (arg_sig, &dim_sig, 10);
00804
00805
00806
00807 if (num_dims == 0) {
00808 if (dra != NULL) {
00809
00810
00811 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00812 WN_Get_Linenum(pu_wn),
00813 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00814 "cannot be satisfied -- non-reshaped argument passed to reshaped formal parameter");
00815
00816
00817 return NULL;
00818 }
00819 else {
00820 arg_sig = strchr(arg_sig, DRA_ARG_SEPARATOR);
00821 *bufptr++ = '0';
00822 *bufptr++ = DRA_ARG_SEPARATOR;
00823 continue;
00824 }
00825 }
00826
00827
00828
00829
00830 if (TY_kind(arg_ty) != KIND_ARRAY) {
00831
00832
00833 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00834 WN_Get_Linenum(pu_wn),
00835 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00836 "cannot be satisfied -- reshaped argument passed to a non-array formal parameter");
00837
00838
00839 return NULL;
00840 }
00841
00842 if (num_dims != TY_AR_ndims(arg_ty) ||
00843 (dra != NULL && num_dims != dra->Num_Dims())) {
00844
00845
00846 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00847 WN_Get_Linenum(pu_wn),
00848 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00849 "cannot be satisfied -- reshaped argument and matching formal parameter have different ranks");
00850
00851
00852 return NULL;
00853 }
00854
00855
00856 INT64 elem_size = (INT64) strtol(dim_sig+1, &dim_sig, 10);
00857
00858 if (elem_size != TY_size(TY_AR_etype(arg_ty)) ||
00859 (dra != NULL && elem_size != dra->Element_Size())) {
00860
00861
00862 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00863 WN_Get_Linenum(pu_wn),
00864 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00865 "cannot be satisfied -- reshaped argument and matching formal parameter have different element sizes");
00866
00867
00868 return NULL;
00869 }
00870
00871
00872 if (dra != NULL) {
00873
00874
00875 if (!DRA_Info_Matches_Encoding(dra, dim_sig+1)) {
00876
00877
00878 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00879 WN_Get_Linenum(pu_wn),
00880 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00881 "cannot be satisfied -- reshaping distributions of arguments and formal parameters do not match");
00882
00883
00884 return NULL;
00885 }
00886 else {
00887
00888
00889 arg_sig = strchr(arg_sig, DRA_ARG_SEPARATOR);
00890 *bufptr++ = '0';
00891 *bufptr++ = DRA_ARG_SEPARATOR;
00892 continue;
00893 }
00894 }
00895
00896
00897
00898
00899
00900 while (*arg_sig != DRA_NDIMS_END) {
00901 *bufptr++ = *arg_sig++;
00902 }
00903
00904
00905
00906 arg_sig++;
00907 while (*arg_sig++ != DRA_ESIZE_END);
00908
00909
00910
00911 while (*arg_sig != DRA_ARG_SEPARATOR) {
00912 *bufptr++ = *arg_sig++;
00913 }
00914 *bufptr++ = DRA_ARG_SEPARATOR;
00915 }
00916
00917
00918
00919 if (bufptr == buf) {
00920 return NULL;
00921 }
00922
00923 *bufptr = '\0';
00924
00925
00926
00927
00928
00929 if (arg_pos < WN_num_formals(pu_wn)) {
00930 ErrMsgSrcpos(EC_DRA_bad_clone_request,
00931 WN_Get_Linenum(pu_wn),
00932 DRA_Demangle(clone_name, DRA_DIMS_COLUMNWISE),
00933 "has incomplete argument list");
00934 }
00935
00936 return buf;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 static void
00967 DRA_Add_Clone (PU_Info *orig_pu,
00968 MEM_POOL *mem_pool,
00969 STR_IDX clone_name,
00970 char *arg_sig,
00971 BOOL pu_has_feedback)
00972 {
00973
00974
00975 MEM_POOL *save_pu_pool_ptr = MEM_pu_pool_ptr;
00976 MEM_POOL *save_wn_pool_ptr = WN_mem_pool_ptr;
00977
00978
00979
00980
00981 Set_PU_Info_symtab_ptr(orig_pu, NULL);
00982 Save_Local_Symtab(CURRENT_SYMTAB, orig_pu);
00983
00984
00985
00986 MEM_pu_pool_ptr = mem_pool;
00987 WN_mem_pool_ptr = mem_pool;
00988
00989
00990
00991 IPO_CLONE clone(PU_Info_tree_ptr(orig_pu),
00992 Scope_tab,
00993 CURRENT_SYMTAB,
00994 PU_Info_maptab(orig_pu),
00995 mem_pool,
00996 mem_pool);
00997
00998 ST* orig_st = ST_ptr(PU_Info_proc_sym(orig_pu));
00999
01000
01001
01002 MANGLED_FUNC *clone_desc = DRA_func_table->Find(clone_name);
01003
01004
01005
01006 if (clone_desc == NULL) {
01007 clone_desc = CXX_NEW(MANGLED_FUNC, &MEM_src_pool);
01008
01009
01010 PU_IDX pu_idx;
01011 PU& pu = New_PU (pu_idx);
01012 Pu_Table[pu_idx] = Pu_Table[ST_pu(orig_st)];
01013
01014
01015 clone_desc->st = New_ST (ST_level(orig_st));
01016 ST_Init (clone_desc->st,
01017 clone_name,
01018 CLASS_FUNC,
01019 SCLASS_TEXT,
01020 ST_export(orig_st),
01021 pu_idx);
01022
01023 clone_desc->is_called = FALSE;
01024 DRA_func_table->Enter(clone_name, clone_desc);
01025 }
01026
01027 clone_desc->is_clone = TRUE;
01028 Set_ST_sclass (clone_desc->st, SCLASS_TEXT);
01029 if (Run_cg) {
01030 Set_ST_base (clone_desc->st, ST_base(orig_st));
01031 }
01032
01033
01034
01035 clone.New_Clone(clone_desc->st);
01036
01037
01038
01039 if (pu_has_feedback) {
01040 DevWarn("Need to fix up feedback in DRA_Add_Clone\n");
01041 }
01042 #if TODO
01043 FEEDBACK cloned_fb(clone.Get_Cloned_PU(), mem_pool);
01044 FB_IPA_Clone(Cur_PU_Feedback, clone_node()->Feedback,
01045 WN_func_body(Callee_Wn ()), clone.Get_Cloned_PU(),
01046 1.0f);
01047 #endif
01048
01049
01050
01051 Scope_tab[CURRENT_SYMTAB] =
01052 clone.Get_sym()->Get_cloned_scope_tab()[CURRENT_SYMTAB];
01053 Scope_tab[CURRENT_SYMTAB].st = clone_desc->st;
01054
01055
01056
01057 DRA_Insert_Pragmas(clone.Get_Cloned_PU(), arg_sig);
01058
01059
01060
01061 Set_FILE_INFO_has_inlines (File_info);
01062 DST_IDX new_pu_dst =
01063 DST_enter_cloned_subroutine(DST_get_compile_unit(),
01064 PU_Info_pu_dst(orig_pu),
01065 clone.Get_Func_ST(),
01066 Current_DST,
01067 clone.Get_sym());
01068
01069
01070
01071 PU_Info *new_pu = CXX_NEW(PU_Info, Malloc_Mem_Pool);
01072 PU_Info_init(new_pu);
01073
01074
01075
01076 PU_Info_next(new_pu) = PU_Info_next(orig_pu);
01077 PU_Info_next(orig_pu) = new_pu;
01078
01079
01080
01081 Set_PU_Info_flags(new_pu, PU_IS_COMPILER_GENERATED);
01082 Set_PU_Info_flags(new_pu, PU_IS_DRA_CLONE);
01083 Set_PU_Info_pu_dst(new_pu, new_pu_dst);
01084
01085 Set_PU_Info_tree_ptr(new_pu, clone.Get_Cloned_PU());
01086 PU_Info_proc_sym(new_pu) = ST_st_idx(clone.Get_Func_ST());
01087 PU_Info_maptab(new_pu) = clone.Get_Cloned_maptab();
01088
01089 Set_PU_Info_state(new_pu, WT_TREE, Subsect_InMem);
01090 Set_PU_Info_state(new_pu, WT_SYMTAB, Subsect_InMem);
01091 Set_PU_Info_state(new_pu, WT_PROC_SYM, Subsect_InMem);
01092 #if 0
01093 Set_PU_Info_state(new_pu, WT_DEPGRAPH, Subsect_InMem);
01094 Set_PU_Info_depgraph_ptr(new_pu, NULL);
01095 #endif
01096
01097 if (pu_has_feedback) {
01098 Set_PU_Info_state(new_pu, WT_FREQ, Subsect_InMem);
01099 }
01100
01101
01102
01103 Set_PU_mp_needs_lno(PU_Info_pu(new_pu));
01104
01105
01106
01107 Current_Map_Tab = PU_Info_maptab(orig_pu);
01108
01109
01110
01111 MEM_pu_pool_ptr = save_pu_pool_ptr;
01112 WN_mem_pool_ptr = save_wn_pool_ptr;
01113
01114
01115
01116 Set_PU_Info_symtab_ptr(new_pu, NULL);
01117 Save_Local_Symtab(CURRENT_SYMTAB, new_pu);
01118
01119
01120
01121 Restore_Local_Symtab(orig_pu);
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 static WN*
01140 Find_Insertion_Point (WN *pu_wn,
01141 char *arg_sig)
01142 {
01143 WN *preamble_wn = Get_Preamble_End(pu_wn);
01144
01145 if (ONST (SYMTAB_src_lang(Current_Symtab) != SYMTAB_C_LANG &&
01146 SYMTAB_src_lang(Current_Symtab) != SYMTAB_CXX_LANG,
01147 PU_src_lang(Get_Current_PU()) != PU_C_LANG &&
01148 PU_src_lang(Get_Current_PU()) != PU_CXX_LANG)) {
01149 return preamble_wn;
01150 }
01151
01152 WN *current_wn = preamble_wn;
01153
01154 for (INT16 arg_pos = 0; *arg_sig; arg_sig++, arg_pos++ ) {
01155
01156
01157
01158 INT16 num_dims = (INT16) strtol (arg_sig, &arg_sig, 10);
01159 ST *arg_st = WN_st(WN_kid(pu_wn, arg_pos));
01160 TY_IDX arg_ty = Get_Array_Type(arg_st);
01161
01162 for (INT16 dim = 0; dim < num_dims; dim++) {
01163
01164 if (*arg_sig++ == DRA_CYCLIC_CODE) {
01165 INT64 chunk = (INT64) strtol (arg_sig, &arg_sig, 10);
01166 }
01167
01168
01169 if (!TY_AR_const_ubnd(arg_ty, num_dims-1-dim) &&
01170 TY_AR_ubnd_val(arg_ty, num_dims-1-dim) &&
01171 strncmp(ST_name(TY_AR_ubnd_var(arg_ty, num_dims-1-dim)),
01172 Temp_Symbol_Prefix "__vla_bound",
01173 sizeof (Temp_Symbol_Prefix "__vla_bound") - 1 ) == 0) {
01174
01175 ST* vlabound_st = ONST(WN_st(TY_AR_ubnd_tree(arg_ty, dim)),
01176 &(St_Table[TY_AR_ubnd_var(arg_ty, num_dims-1-dim)]));
01177
01178
01179
01180 BOOL saw_preamble = FALSE;
01181 BOOL saw_current = FALSE;
01182 WN *wn = WN_first(WN_func_body(pu_wn));
01183
01184 while (wn) {
01185
01186 if (WN_operator(wn) == OPR_PRAGMA &&
01187 WN_pragma(wn) == WN_PRAGMA_PREAMBLE_END) {
01188 saw_preamble = TRUE;
01189 }
01190 if (wn == current_wn) saw_current = TRUE;
01191
01192 if (WN_operator(wn) == OPR_STID &&
01193 WN_st(wn) == vlabound_st) {
01194
01195 if (saw_preamble && saw_current) {
01196
01197
01198 current_wn = wn;
01199
01200
01201 if (WN_next(wn) &&
01202 WN_operator(WN_next(wn)) == OPR_XPRAGMA &&
01203 WN_operator(WN_kid0(WN_next(wn)))==OPR_LDID &&
01204 WN_st(WN_kid0(WN_next(wn))) == vlabound_st) {
01205
01206 current_wn = WN_next(wn);
01207 }
01208 }
01209 else {
01210
01211 }
01212 break;
01213 }
01214 wn = WN_next(wn);
01215 }
01216
01217 FmtAssert (wn,
01218 ("Find_Insertion_Point: No STID vla_bound for %s\n",
01219 ST_name(arg_st)));
01220 }
01221 }
01222 }
01223 return current_wn;
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 static void
01237 DRA_Insert_Pragmas(WN *pu_wn,
01238 char *arg_sig)
01239 {
01240
01241
01242
01243
01244
01245
01246
01247
01248 WN *block = WN_func_body(pu_wn);
01249
01250 WN *current = Find_Insertion_Point(pu_wn, arg_sig);
01251
01252 for (INT16 arg_pos = 0; *arg_sig; arg_sig++, arg_pos++ ) {
01253
01254
01255
01256 INT16 num_dims = (INT16) strtol (arg_sig, &arg_sig, 10);
01257 ST *arg_st = WN_st(WN_kid(pu_wn, arg_pos));
01258 TY_IDX arg_ty = Get_Array_Type(arg_st);
01259
01260 for (INT16 dim = 0; dim < num_dims; dim++) {
01261
01262
01263
01264 WN *pwn = WN_CreatePragma(WN_PRAGMA_DISTRIBUTE_RESHAPE, arg_st, 0, 0);
01265 WN_pragma_index(pwn) = dim;
01266
01267 WN_set_pragma_compiler_generated(pwn);
01268 WN_INSERT_BlockAfter(block, current, pwn);
01269 current = pwn;
01270
01271 switch (*arg_sig++) {
01272
01273 case DRA_BLOCK_CODE:
01274 WN_pragma_distr_type(pwn) = DISTRIBUTE_BLOCK;
01275 break;
01276
01277 case DRA_STAR_CODE:
01278 WN_pragma_distr_type(pwn) = DISTRIBUTE_STAR;
01279 break;
01280
01281 case DRA_CYCLIC_CODE:
01282 {
01283 INT64 chunk = (INT64) strtol (arg_sig, &arg_sig, 10);
01284 if (chunk != 0) {
01285 WN_pragma_distr_type(pwn) = DISTRIBUTE_CYCLIC_CONST;
01286 WN_pragma_arg2(pwn) = chunk;
01287 }
01288 else {
01289
01290
01291 WN_pragma_distr_type(pwn) = DISTRIBUTE_CYCLIC_EXPR;
01292 WN *xpwn = WN_CreateXpragma(WN_PRAGMA_DISTRIBUTE_RESHAPE,
01293 arg_st, 1);
01294 WN_kid(xpwn, 0) = WN_Intconst(MTYPE_I8, 0);
01295
01296 WN_set_pragma_compiler_generated(xpwn);
01297 WN_INSERT_BlockAfter(block, current, xpwn);
01298 current = xpwn;
01299 }
01300 }
01301 break;
01302
01303 default:
01304 FmtAssert(FALSE,
01305 ("Unrecognized distribution in the mangled name"));
01306 }
01307
01308
01309
01310 WN *xpwn = WN_CreateXpragma(WN_PRAGMA_DISTRIBUTE_RESHAPE, arg_st, 1);
01311
01312 INT16 st_dim = dim;
01313
01314 WN *lb;
01315 if (TY_AR_const_lbnd(arg_ty, st_dim)) {
01316 lb = WN_Intconst(MTYPE_I8, TY_AR_lbnd_val(arg_ty, st_dim));
01317 }
01318 else {
01319 ST_IDX lb_st = TY_AR_lbnd_var(arg_ty, st_dim);
01320 TY_IDX lb_ty = ST_type(lb_st);
01321 lb = WN_CreateLdid(OPCODE_make_op(OPR_LDID,
01322 TY_mtype(lb_ty),
01323 TY_mtype(lb_ty)),
01324 0,
01325 lb_st,
01326 lb_ty);
01327 }
01328
01329 WN *ub;
01330 if (TY_AR_const_ubnd(arg_ty, st_dim)) {
01331 ub = WN_Intconst(MTYPE_I8, TY_AR_ubnd_val(arg_ty, st_dim));
01332 }
01333 else {
01334 ST_IDX ub_st = TY_AR_ubnd_var(arg_ty, st_dim);
01335 TY_IDX ub_ty = ST_type(ub_st);
01336 ub = WN_CreateLdid(OPCODE_make_op(OPR_LDID,
01337 TY_mtype(ub_ty),
01338 TY_mtype(ub_ty)),
01339 0,
01340 ub_st,
01341 ub_ty);
01342 }
01343
01344 WN_kid(xpwn, 0) = WN_Add(MTYPE_I8,
01345 WN_Sub(MTYPE_I8, ub, lb),
01346 WN_Intconst(MTYPE_I8, 1));
01347
01348 WN_set_pragma_compiler_generated(xpwn);
01349 WN_INSERT_BlockAfter(block, current, xpwn);
01350 current = xpwn;
01351 }
01352 }
01353 }
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366 static void
01367 DRA_Collect_Commons(WN *wn, DRA_COMMON_HASH_TABLE *dra_common_ht)
01368 {
01369 if (wn == NULL) return;
01370
01371 OPCODE opc = WN_opcode(wn);
01372
01373 ST *st = OPCODE_has_sym(opc) ? WN_st(wn) : NULL;
01374
01375 if (st &&
01376 (ST_base(st) != st) &&
01377 (ST_sclass(st) == SCLASS_COMMON || ST_sclass(st) == SCLASS_DGLOBAL) &&
01378 (ST_class(ST_base(st)) == CLASS_VAR &&
01379 TY_kind(ST_type(ST_base(st))) == KIND_STRUCT)) {
01380
01381 dra_common_ht->Enter_If_Unique (ST_st_idx(ST_base(st)), TRUE);
01382 }
01383
01384
01385
01386 if (opc == OPC_BLOCK) {
01387 WN *kid = WN_first(wn);
01388 while (kid) {
01389 DRA_Collect_Commons (kid, dra_common_ht);
01390 kid = WN_next(kid);
01391 }
01392 }
01393 else {
01394 for (INT i=0; i<WN_kid_count(wn); i++) {
01395 DRA_Collect_Commons (WN_kid(wn,i), dra_common_ht);
01396 }
01397 }
01398 }
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 static void
01413 DRA_Process_Commons(DRA_HASH_TABLE *dra_table,
01414 DRA_COMMON_HASH_TABLE *dra_common_ht)
01415 {
01416 BOOL seen_common = FALSE;
01417 BOOL new_common = FALSE;
01418 UINT bufsize = 1024;
01419 char *buf = (char *) alloca(bufsize);
01420 char *bufptr = buf;
01421 char *common_name = NULL;
01422 INT64 common_offset;
01423 INT64 non_dra_start = 0;
01424 INT64 non_dra_end = 0;
01425 ST *st;
01426 INT i;
01427
01428
01429 FOREACH_SYMBOL (GLOBAL_SYMTAB, st, i) {
01430
01431
01432
01433 ST_SCLASS st_sclass = ST_sclass(st);
01434
01435 if (st_sclass == SCLASS_COMMON &&
01436 ST_st_idx(st) == ST_base_idx(st) &&
01437 dra_common_ht->Find(ST_st_idx(st))) {
01438
01439
01440
01441 char *st_name = ST_name(st);
01442
01443
01444
01445 char *dot = strchr(st_name, '.');
01446
01447
01448
01449 if (dot == NULL) {
01450 if (common_name == NULL ||
01451 strcmp(st_name, common_name) != 0) {
01452 common_name = strcpy((char *) alloca(strlen(st_name)+1),
01453 st_name);
01454 new_common = TRUE;
01455 }
01456 common_offset = 0;
01457 }
01458
01459
01460
01461 else {
01462 if (common_name == NULL ||
01463 strncmp(st_name, common_name, dot-st_name) != 0) {
01464 common_name = strncpy((char *) alloca(dot-st_name+1),
01465 st_name, dot-st_name);
01466 common_name[dot-st_name] = '\0';
01467 new_common = TRUE;
01468 }
01469 common_offset = strtol(dot+1, NULL, 10);
01470 }
01471
01472 if (new_common) {
01473
01474
01475
01476 if (non_dra_end - non_dra_start > 0) {
01477 bufptr += sprintf(bufptr, " %lld\n", non_dra_end - non_dra_start);
01478 }
01479 else if (seen_common) {
01480 *bufptr++ = '\n';
01481 }
01482
01483
01484
01485 INT name_len = strlen(common_name);
01486
01487 if (bufptr - buf + name_len + 21 >= bufsize) {
01488 bufsize *= 2;
01489 char *newbuf = (char *) alloca(bufsize);
01490 buf = strcpy(newbuf, buf);
01491 bufptr = buf + strlen(buf);
01492 }
01493
01494 (void) strcpy(bufptr, common_name);
01495 bufptr += name_len;
01496
01497 non_dra_end = non_dra_start = 0;
01498 new_common = FALSE;
01499 }
01500
01501 seen_common = TRUE;
01502 }
01503
01504 else if (ST_st_idx(st) != ST_base_idx(st) &&
01505 ST_sclass(ST_base(st)) == SCLASS_COMMON &&
01506 dra_common_ht->Find(ST_st_idx(ST_base(st)))) {
01507
01508 TY_IDX ty = ST_type(st);
01509
01510 DRA_INFO *dra = (dra_table ? dra_table->Find(st) : NULL);
01511
01512 if (dra != NULL) {
01513
01514 INT16 ndims = TY_AR_ndims(ty);
01515
01516
01517
01518
01519
01520
01521
01522
01523 if (bufptr - buf + 31 + ndims*69 + 21 >= bufsize) {
01524 bufsize *= 2;
01525 char *newbuf = (char *) alloca(bufsize);
01526 buf = strcpy(newbuf, buf);
01527 bufptr = buf + strlen(buf);
01528 }
01529
01530 if (non_dra_end - non_dra_start > 0) {
01531 bufptr += sprintf(bufptr, " %lld", non_dra_end - non_dra_start);
01532 }
01533 non_dra_start = common_offset + ST_ofst(st) + TY_size(ty);
01534 non_dra_end = non_dra_start;
01535
01536 bufptr +=
01537 sprintf(bufptr, " DRA_%lld_%d", TY_size(TY_AR_etype(ty)), ndims);
01538
01539 for (INT16 dim = 0; dim < ndims; ++dim) {
01540
01541 bufptr += sprintf(bufptr,
01542 "_%lld:%lld:",
01543 TY_AR_lbnd_val(ty, ndims-1-dim),
01544 TY_AR_ubnd_val(ty, ndims-1-dim));
01545
01546 switch (dra->Distr_Type(dim)) {
01547 case DISTRIBUTE_STAR:
01548 *bufptr++ = DRA_STAR_CODE;
01549 break;
01550 case DISTRIBUTE_BLOCK:
01551 *bufptr++ = DRA_BLOCK_CODE;
01552 break;
01553 case DISTRIBUTE_CYCLIC_CONST:
01554 *bufptr++ = DRA_CYCLIC_CODE;
01555 bufptr += sprintf(bufptr, "%lld", dra->Chunk_Const_Val(dim));
01556 break;
01557 case DISTRIBUTE_CYCLIC_EXPR:
01558 *bufptr++ = DRA_CYCLIC_CODE;
01559 break;
01560 }
01561 }
01562 }
01563
01564 else if (common_offset + ST_ofst(st) + TY_size(ty) > non_dra_end) {
01565 non_dra_end = common_offset + ST_ofst(st) + TY_size(ty);
01566 }
01567 }
01568 }
01569
01570 if (bufptr != buf) {
01571 if (non_dra_end - non_dra_start > 0) {
01572 bufptr += sprintf(bufptr, " %lld\n", non_dra_end - non_dra_start);
01573 }
01574 else {
01575 *bufptr++ = '\n';
01576 }
01577 write(DRA_file_desc, (void*)buf, bufptr-buf);
01578 }
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594 static void
01595 DRA_Process_Globals(DRA_HASH_TABLE *dra_table)
01596 {
01597 UINT bufsize = 1024;
01598 char *buf = (char *) alloca(bufsize);
01599 char *bufptr = buf;
01600 ST *st;
01601 INT i;
01602
01603 {
01604
01605 static BOOL done_globals = FALSE;
01606 if (done_globals) return;
01607 done_globals = TRUE;
01608 }
01609
01610 FOREACH_SYMBOL (GLOBAL_SYMTAB, st, i) {
01611
01612 if (ST_class(st) != CLASS_VAR) continue;
01613
01614
01615
01616 if ((ST_sclass(st) == SCLASS_COMMON) ||
01617 (ST_sclass(st) == SCLASS_DGLOBAL &&
01618
01619
01620 (TY_kind(ST_type(st)) == KIND_STRUCT ||
01621 (ST_class(ST_base(st)) == CLASS_VAR &&
01622 TY_kind(ST_type(ST_base(st))) == KIND_STRUCT)))) {
01623 continue;
01624 }
01625
01626 bufptr = buf;
01627
01628
01629
01630 TY_IDX ty = Get_Original_Type(st);
01631 if (ty && TY_kind(ty) == KIND_ARRAY) {
01632
01633 char* st_name = ST_name(st);
01634 INT name_len = strlen(st_name);
01635
01636 if (bufptr - buf + name_len + 21 >= bufsize) {
01637 bufsize *= 2;
01638 char *newbuf = (char *) alloca(bufsize);
01639 buf = strcpy(newbuf, buf);
01640 bufptr = buf + strlen(buf);
01641 }
01642
01643 strcpy (bufptr, st_name);
01644 bufptr += name_len;
01645
01646 DRA_INFO* dra = (dra_table ? dra_table->Find(st) : NULL);
01647
01648 if (dra != NULL) {
01649
01650
01651
01652 INT16 ndims = TY_AR_ndims(ty);
01653
01654
01655
01656
01657
01658
01659 if (bufptr - buf + 31 + ndims*69 >= bufsize) {
01660 bufsize *= 2;
01661 char *newbuf = (char *) alloca(bufsize);
01662 buf = strcpy(newbuf, buf);
01663 bufptr = buf + strlen(buf);
01664 }
01665
01666 bufptr +=
01667 sprintf(bufptr, " DRA_%lld_%d", TY_size(TY_AR_etype(ty)), ndims);
01668
01669
01670
01671 for (INT16 dim = 0; dim < ndims; ++dim) {
01672
01673 bufptr += sprintf(bufptr,
01674 "_%lld:%lld:",
01675 TY_AR_lbnd_val(ty, ndims-1-dim),
01676 TY_AR_ubnd_val(ty, ndims-1-dim));
01677
01678 switch (dra->Distr_Type(dim)) {
01679 case DISTRIBUTE_STAR:
01680 *bufptr++ = DRA_STAR_CODE;
01681 break;
01682 case DISTRIBUTE_BLOCK:
01683 *bufptr++ = DRA_BLOCK_CODE;
01684 break;
01685 case DISTRIBUTE_CYCLIC_CONST:
01686 *bufptr++ = DRA_CYCLIC_CODE;
01687 bufptr += sprintf(bufptr, "%lld", dra->Chunk_Const_Val(dim));
01688 break;
01689 case DISTRIBUTE_CYCLIC_EXPR:
01690 *bufptr++ = DRA_CYCLIC_CODE;
01691 break;
01692 }
01693 }
01694 *bufptr++ = '\n';
01695 }
01696 else {
01697
01698
01699 bufptr += sprintf (bufptr, " %lld", TY_size(ty));
01700 *bufptr++ = '\n';
01701 }
01702 write(DRA_file_desc, (void*)buf, bufptr-buf);
01703 }
01704 }
01705 }
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718 static BOOL
01719 DRA_Info_Matches_Encoding(DRA_INFO *dra,
01720 char *arg_sig)
01721 {
01722 INT16 num_dims = dra->Num_Dims();
01723 for (INT16 dim = 0; dim < num_dims; dim++) {
01724
01725 switch (*arg_sig++) {
01726
01727 case DRA_BLOCK_CODE:
01728 if (dra->Distr_Type(dim) != DISTRIBUTE_BLOCK) {
01729 return FALSE;
01730 }
01731 break;
01732
01733 case DRA_STAR_CODE:
01734 if (dra->Distr_Type(dim) != DISTRIBUTE_STAR) {
01735 return FALSE;
01736 }
01737 break;
01738
01739 case DRA_CYCLIC_CODE:
01740 {
01741 INT64 chunk = (INT64) strtol (arg_sig, &arg_sig, 10);
01742 if (chunk != 0) {
01743 if (dra->Distr_Type(dim) != DISTRIBUTE_CYCLIC_CONST ||
01744 dra->Chunk_Const_Val(dim) != chunk) {
01745 return FALSE;
01746 }
01747 }
01748 else {
01749 if (dra->Distr_Type(dim) != DISTRIBUTE_CYCLIC_EXPR) {
01750 return FALSE;
01751 }
01752 }
01753 }
01754 break;
01755
01756 default:
01757 FmtAssert(FALSE,
01758 ("Uncrecognized distribution in the mangled name"));
01759 }
01760 }
01761 return TRUE;
01762 }