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 #ifdef USE_PCH
00037 #include "lno_pch.h"
00038 #endif // USE_PCH
00039 #pragma hdrstop
00040
00041 #include <alloca.h>
00042 #include <sys/types.h>
00043 #include <ctype.h>
00044 #include <limits.h>
00045
00046 #include "pu_info.h"
00047 #include "wn.h"
00048 #include "lego.h"
00049 #include "cxx_memory.h"
00050 #include "lego_pragma.h"
00051 #include "lego_gen.h"
00052 #include "array_lower.h"
00053 #include "tracing.h"
00054 #include "lnopt_main.h"
00055 #include "ir_reader.h"
00056 #include "lwn_util.h"
00057 #include "lnoutils.h"
00058 #include "irbdata.h"
00059 #include "stblock.h"
00060 #include "tile.h"
00061 #include "data_layout.h"
00062 #include "permute.h"
00063 #include "soe.h"
00064 #include "cond.h"
00065 #include "strtab.h"
00066 #include "ff_pragmas.h"
00067
00068
00069
00070
00071
00072
00073 extern ST* Section_Variable_ST (char* name, TY_IDX daty, BOOL is_global);
00074 extern void Do_Loop_Explicit_Affinity (WN* loop);
00075 extern char* Cur_PU_Name;
00076 extern void Whack_Do_Loops (WN* func_nd);
00077
00078 extern BOOL Run_Dsm_Check;
00079 extern void EC_Array_Portion_Calls (WN* func_nd);
00080 extern void Parallel_And_Padding_Phase(PU_Info* current_pu, WN* func_nd);
00081
00082
00083
00084
00085
00086
00087
00088 extern "C" {
00089 void Lego_File_Init (void);
00090 void Mp_File_Init (void);
00091 void Lego_File_Fini (void);
00092 }
00093 extern void Lego_OZero_Driver(PU_Info* current_pu, WN* func_nd);
00094 extern void Lego_Read_Pragmas(WN* func_nd);
00095 extern void Lego_Lower_Pragmas(WN* func_nd);
00096 extern void Lego_PU_Init(void);
00097 extern void Lego_PU_Fini(void);
00098
00099 extern INT32 da_count;
00100 INT32 da_count = 0;
00101
00102 extern MEM_POOL LEGO_memory_pool, *LEGO_pool;
00103 MEM_POOL LEGO_memory_pool, *LEGO_pool;
00104
00105 extern BOOL Debug_Lego;
00106 extern BOOL Verbose_Lego;
00107 BOOL Debug_Lego = FALSE;
00108 BOOL Verbose_Lego = FALSE;
00109
00110 extern BOOL disable_divmod_opts;
00111 BOOL disable_divmod_opts = FALSE;
00112
00113 extern BOOL disable_rr_maps;
00114 BOOL disable_rr_maps = TRUE;
00115
00116
00117
00118
00119
00120 extern WN_MAP Safe_Spec_MAP;
00121 WN_MAP Safe_Spec_Map = WN_MAP_UNDEFINED;
00122
00123 extern WN_MAP RR_Map;
00124 WN_MAP RR_Map = WN_MAP_UNDEFINED;
00125
00126 BOOL PU_has_reshaped_commons = FALSE;
00127
00128
00129
00130
00131
00132
00133 static INT64 pu_count = 0;
00134 static void Dealloc_HashTable_Entries ();
00135 static void Delete_Distr_Pragmas (DISTR_ARRAY* dact);
00136
00137
00138
00139
00140
00141
00142
00143
00144 static void Dealloc_HashTable_Entries () {
00145 for (INT i=0; i<da_stack->Elements(); i++) {
00146 DISTR_INFO* dinfo = da_stack->Bottom_nth(i);
00147 #ifdef Is_True_On
00148
00149 Is_True (da_hash->Find(dinfo->Array_ST()) == dinfo,
00150 ("Mismatch between dinfo stack and hash-table"));
00151 da_hash->Remove(dinfo->Array_ST());
00152 #endif
00153 CXX_DELETE (dinfo, LEGO_pool);
00154 }
00155
00156 #ifdef Is_True_On
00157 {
00158
00159 HASH_TABLE_ITER<ST*, DISTR_INFO*> iter (da_hash);
00160 ST* st;
00161 DISTR_INFO* dinfo;
00162 while (iter.Step (&st, &dinfo)) {
00163 FmtAssert (FALSE, ("Hash-table is not empty. Has array %s!",
00164 ST_name(st)));
00165 }
00166 }
00167 #endif
00168 }
00169
00170
00171
00172
00173
00174
00175 extern void Lego_Read_Pragmas (WN* func_nd) {
00176
00177 if (Debug_Lego) printf ("===== DSM Processing function %s =====\n",
00178 Cur_PU_Name);
00179
00180 Read_Distr_Pragmas (func_nd);
00181
00182 if (Debug_Lego) {
00183 printf("===== Done Reading Pragmas ====\n");
00184
00185
00186 printf("===== Begin Sanity Tests ====\n");
00187 printf("(**) Du_Sanity_Check\n");
00188 Du_Sanity_Check(func_nd);
00189 #ifdef Is_True_On
00190 printf("(**) MP_Sanity_Check\n");
00191 MP_Sanity_Check_Func(func_nd);
00192 #endif
00193 printf("(**) LWN_Check_Parentize\n");
00194 LWN_Check_Parentize(func_nd);
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 extern void Lego_Compute_Tile_Peel (WN* func_nd) {
00205 if (!Get_Trace(TP_LNOPT2, TT_LEGO_DISABLE_IMPLICIT_AFFINITY))
00206 Whack_Do_Loops (func_nd);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 static void Find_Buddy () {
00217
00218 for (INT i=1; i<da_stack->Elements(); i++) {
00219 DISTR_INFO* dinfo = da_stack->Bottom_nth(i);
00220 DISTR_ARRAY* dact = NULL;
00221
00222
00223
00224
00225 if (dinfo->Num_Dact()) {
00226 dact = dinfo->Get_Dact (0);
00227 for (INT j=0; j<i; j++) {
00228 DISTR_INFO* old_dinfo = da_stack->Bottom_nth(j);
00229 if (old_dinfo->IsReshaped()) {
00230 DISTR_ARRAY* old_dact = old_dinfo->Get_Dact(0);
00231 if (dact->DACT_Equiv (old_dact)) {
00232 dinfo->Set_Buddy (old_dinfo);
00233 break;
00234 }
00235 }
00236 }
00237 }
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246 extern void Lego_Lower_Pragmas (WN* func_nd) {
00247 Lower_Distr_Pragmas (func_nd);
00248 if (Run_Dsm_Check)
00249 EC_Array_Portion_Calls(func_nd);
00250 Find_Buddy ();
00251 if (!Get_Trace(TP_LNOPT2, TT_LEGO_PRAGMAS_ONLY))
00252 Lower_Array_Accesses (func_nd);
00253 if (PU_has_reshaped_commons) Rewrite_Reshaped_Commons (func_nd);
00254
00255 if (Debug_Lego) {
00256 printf("===== Done Lowering Arrays ====\n");
00257
00258
00259 printf("===== Begin Sanity Tests ====\n");
00260 printf("(**) Du_Sanity_Check\n");
00261 Du_Sanity_Check(func_nd);
00262 #ifdef Is_True_On
00263 printf("(**) MP_Sanity_Check\n");
00264 MP_Sanity_Check_Func(func_nd);
00265 #endif
00266 printf("(**) LWN_Check_Parentize\n");
00267 LWN_Check_Parentize(func_nd);
00268 }
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 extern void Lego_OZero_Driver(PU_Info* current_pu,
00280 WN* func_nd)
00281 {
00282 extern BOOL Run_lno;
00283
00284 Lego_PU_Init ();
00285
00286 BOOL has_do_loops = Mark_Code(func_nd, TRUE, TRUE);
00287 Lego_Read_Pragmas (func_nd);
00288
00289 void Lego_Fix_Local(WN *func_nd);
00290 if (LNO_Run_Lego_Localizer) Lego_Fix_Local(func_nd);
00291
00292 void Lego_Fix_IO(WN *func_nd, BOOL *has_dos);
00293 Lego_Fix_IO(func_nd,&has_do_loops);
00294
00295
00296 LNO_Build_Access(func_nd,&LNO_default_pool);
00297 if (LNO_Verbose) {
00298 LNO_Print_Access(TFile,func_nd);
00299 }
00300
00301
00302 if (!has_do_loops) return;
00303
00304
00305 if (Eliminate_Dead_SCF(func_nd,LWN_Delete_Tree)) {
00306 Mark_Code(func_nd, FALSE, TRUE);
00307
00308 }
00309
00310
00311 BOOL graph_is_ok = Build_Array_Dependence_Graph (func_nd);
00312
00313 if (graph_is_ok) {
00314 Lego_Mp_Tile(func_nd, TRUE);
00315 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2) ||
00316 Get_Trace(TP_LNOPT,TT_LNO_DEP)) {
00317 fprintf(TFile, "%sLNO dep graph for CG, after LNO\n%s", DBar, DBar);
00318 Current_Dep_Graph->Print(TFile);
00319 fprintf(TFile, "%s", DBar);
00320 }
00321 if (Run_autopar) {
00322 LWN_Process_FF_Pragmas(func_nd);
00323 Parallel_And_Padding_Phase(current_pu, func_nd);
00324 }
00325 Build_CG_Dependence_Graph (Array_Dependence_Graph);
00326 }
00327 else Build_CG_Dependence_Graph (func_nd);
00328
00329 if (!Get_Trace(TP_LNOPT, TT_LNO_GUARD)) {
00330 Guard_Dos(func_nd);
00331 }
00332
00333 return;
00334 }
00335
00336 static INITO_IDX pu_ino;
00337
00338
00339
00340
00341
00342
00343 extern void Lego_PU_Init (void) {
00344 MEM_POOL_Push (LEGO_pool);
00345
00346 da_hash = CXX_NEW (DA_HASH_TABLE(20, LEGO_pool), LEGO_pool);
00347 da_stack = CXX_NEW (DA_STACK(LEGO_pool), LEGO_pool);
00348 PU_has_reshaped_commons = FALSE;
00349
00350 if (!disable_rr_maps)
00351 RR_Map = WN_MAP_Create(LEGO_pool);
00352
00353
00354
00355
00356 da_count = 0;
00357 char name[64];
00358 sprintf (name, "_da_count_PUnum_%lld", pu_count);
00359 ST* da_count_st = Section_Variable_ST (name, Be_Type_Tbl(MTYPE_I8), TRUE);
00360 pu_ino = New_INITO (da_count_st);
00361 Set_ST_is_initialized(da_count_st);
00362 Allocate_Object(da_count_st);
00363 pu_count++;
00364 }
00365
00366
00367
00368
00369
00370
00371 static void Delete_Distr_Pragmas (DISTR_ARRAY* dact) {
00372 WN* wn = dact->First_Pragma_WN();
00373 WN* end_wn = WN_next(dact->Last_Pragma_WN());
00374 while (wn != end_wn) {
00375 Is_True (WN_operator(wn) == OPR_PRAGMA ||
00376 WN_operator(wn) == OPR_XPRAGMA ||
00377 WN_operator(wn) == OPR_STID,
00378 ("Delete_Distr_Pragmas: Expected a pragma/stid node\n"));
00379 WN* next_wn = WN_next(wn);
00380 LWN_Delete_Tree_From_Block (wn);
00381 wn = next_wn;
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390 static void Delete_All_Distr_Pragmas () {
00391 for (INT i=0; i<da_stack->Elements(); i++) {
00392 DISTR_INFO* dinfo = da_stack->Bottom_nth(i);
00393 INT i;
00394 for (i=0; i<dinfo->Num_Dact(); i++) {
00395 DISTR_ARRAY* dact = dinfo->Get_Dact(i);
00396 Delete_Distr_Pragmas (dact);
00397 }
00398 for (i=0; i<dinfo->Num_Gen_Redistr(); i++) {
00399 DISTR_ARRAY* dact = dinfo->Get_Gen_Redistr(i);
00400 Delete_Distr_Pragmas (dact);
00401 }
00402 }
00403 }
00404
00405
00406
00407
00408
00409
00410 extern void Lego_PU_Fini (void) {
00411
00412
00413
00414 Irb_Init_Integer (8, da_count, 1, pu_ino, INITV_IDX_ZERO);
00415 if (Verbose_Lego) {
00416 extern char* Cur_PU_Name;
00417 printf ("PU: %s, had %d global distributed arrays\n",
00418 Cur_PU_Name, da_count);
00419 }
00420
00421
00422
00423 if (!disable_rr_maps)
00424 WN_MAP_Delete(RR_Map);
00425 RR_Map = WN_MAP_UNDEFINED;
00426
00427 Delete_All_Distr_Pragmas ();
00428 Dealloc_HashTable_Entries ();
00429 CXX_DELETE (da_hash, LEGO_pool);
00430 da_hash = NULL;
00431 CXX_DELETE (da_stack, LEGO_pool);
00432 da_stack = NULL;
00433 MEM_POOL_Pop (LEGO_pool);
00434 }
00435
00436 static INITO_IDX file_ino;
00437 static INITO_IDX version_number_ino;
00438 #define DSM_VERSION_NUMBER 1
00439
00440
00441
00442
00443
00444
00445
00446
00447 extern void Mp_File_Init(void) {
00448 static BOOL Lego_Mp_Special_Array_Initialized = FALSE;
00449 if (!Lego_Mp_Special_Array_Initialized) {
00450 Init_Special_Lego_Mp_Call();
00451 Lego_Mp_Special_Array_Initialized = TRUE;
00452 }
00453 }
00454
00455 extern void Lego_File_Init (void) {
00456
00457 {
00458 static BOOL Lego_File_Inited = FALSE;
00459 if (Lego_File_Inited)
00460 return;
00461 Lego_File_Inited = TRUE;
00462 }
00463
00464 Mp_File_Init ();
00465
00466 {
00467 static BOOL LEGO_pool_initialized = FALSE;
00468 if (!LEGO_pool_initialized) {
00469 MEM_POOL_Initialize (&LEGO_memory_pool, "LEGO_pool", FALSE);
00470 LEGO_pool = &LEGO_memory_pool;
00471 LEGO_pool_initialized = TRUE;
00472 Generate_Runtime_Stuff ();
00473 }
00474 else FmtAssert (FALSE, ("How did LEGO pool get initialized?"));
00475 }
00476
00477
00478 da_global = CXX_NEW (DA_GLOBAL_HASH_TABLE(20, Malloc_Mem_Pool),
00479 Malloc_Mem_Pool);
00480
00481 Verbose_Lego = Get_Trace(TP_LNOPT2, TT_LEGO_VERBOSE);
00482 Debug_Lego = Get_Trace(TP_LNOPT2, TT_LEGO_DEBUG);
00483 disable_divmod_opts = Get_Trace(TP_LNOPT2, TT_LEGO_DISABLE_DIVMOD);
00484
00485 disable_rr_maps = !Get_Trace(TP_LNOPT2, TT_LEGO_DISABLE_RR_MAPS);
00486
00487 if (Verbose_Lego && disable_divmod_opts)
00488 printf ("div/mod optimizations disabled\n");
00489
00490 {
00491
00492 char name[64];
00493 sprintf (name, "_dsm_version_number");
00494 ST* version_number_st = Section_Variable_ST (name,
00495 Be_Type_Tbl(MTYPE_I8),
00496 TRUE);
00497 version_number_ino = New_INITO (version_number_st);
00498 Set_ST_is_initialized(version_number_st);
00499 Allocate_Object (version_number_st);
00500 }
00501
00502 {
00503
00504 char name[64];
00505 sprintf (name, "_pu_count");
00506 ST* pu_count_st = Section_Variable_ST (name, Be_Type_Tbl(MTYPE_I8), TRUE);
00507 file_ino = New_INITO (pu_count_st);
00508 Set_ST_is_initialized(pu_count_st);
00509 Allocate_Object (pu_count_st);
00510 }
00511 if (Verbose_Lego) printf ("Done Lego_File_Init\n");
00512 }
00513
00514
00515
00516
00517
00518
00519 extern void Lego_File_Fini (void) {
00520
00521
00522 {
00523 HASH_TABLE_ITER<ST*, DISTR_GLOBAL_INFO*> iter (da_global);
00524 ST* st;
00525 DISTR_GLOBAL_INFO* dgi;
00526 while (iter.Step (&st, &dgi)) {
00527 CXX_DELETE (dgi, Malloc_Mem_Pool);
00528 }
00529 CXX_DELETE (da_global, Malloc_Mem_Pool);
00530 da_global = NULL;
00531 }
00532
00533 Irb_Init_Integer (8, DSM_VERSION_NUMBER, 1, version_number_ino, INITV_IDX_ZERO);
00534 Irb_Init_Integer (8, pu_count, 1, file_ino, INITV_IDX_ZERO);
00535 if (Verbose_Lego)
00536 printf ("Done Lego_File_Fini: File had %lld PUs\n", pu_count);
00537 MEM_POOL_Delete (LEGO_pool);
00538 }