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 #ifdef _KEEP_RCS_ID
00059 static char *rcs_id = "$Source: /depot/CVSROOT/javi/src/sw/cmplr/be/com/wn_mp_dg.cxx,v $ $Revision: 1.1 $";
00060 #endif
00061
00062 #include <sys/types.h>
00063 #include <elf.h>
00064
00065 #define USE_STANDARD_TYPES
00066
00067 #include <bstring.h>
00068 #include "wn.h"
00069 #include "wn_util.h"
00070 #include "erglob.h"
00071 #include "errors.h"
00072 #include "strtab.h"
00073 #include "symtab.h"
00074 #include "irbdata.h"
00075 #include "dwarf_DST_mem.h"
00076 #include "pu_info.h"
00077 #include "ir_bwrite.h"
00078 #include "ir_bcom.h"
00079 #include "region_util.h"
00080 #include "dep_graph.h"
00081 #include "cxx_hash.h"
00082 #include "wn_mp.h"
00083
00084 typedef HASH_TABLE<VINDEX16,VINDEX16> VV_HASH_TABLE;
00085 typedef STACK<VINDEX16> V_STACK;
00086 static MEM_POOL MP_Dep_Pool;
00087 static BOOL mp_dep_pool_initialized;
00088 void Create_Vertices(WN *wn, VV_HASH_TABLE *parent_to_child,
00089 V_STACK *parent_vertices,
00090 ARRAY_DIRECTED_GRAPH16 *parent_graph,
00091 ARRAY_DIRECTED_GRAPH16 *child_graph);
00092
00093
00094 void MP_Fix_Dependence_Graph(PU_Info *parent_pu_info,
00095 PU_Info *child_pu_info, WN *child_wn)
00096 {
00097 ARRAY_DIRECTED_GRAPH16 *parent_graph =
00098 (ARRAY_DIRECTED_GRAPH16 *) PU_Info_depgraph_ptr(parent_pu_info);
00099 if (!parent_graph) {
00100 Set_PU_Info_depgraph_ptr(child_pu_info,NULL);
00101 return;
00102 }
00103 if (!mp_dep_pool_initialized) {
00104 MEM_POOL_Initialize(&MP_Dep_Pool,"MP_Dep_Pool",FALSE);
00105 mp_dep_pool_initialized = TRUE;
00106 }
00107 MEM_POOL_Push(&MP_Dep_Pool);
00108
00109
00110 ARRAY_DIRECTED_GRAPH16 *child_graph =
00111 CXX_NEW(ARRAY_DIRECTED_GRAPH16(100, 500,
00112 WN_MAP_DEPGRAPH, DEP_ARRAY_GRAPH), Malloc_Mem_Pool);
00113 Set_PU_Info_depgraph_ptr(child_pu_info,child_graph);
00114 Set_PU_Info_state(child_pu_info,WT_DEPGRAPH,Subsect_InMem);
00115
00116
00117
00118 VV_HASH_TABLE *parent_to_child =
00119 CXX_NEW(VV_HASH_TABLE(200,&MP_Dep_Pool),&MP_Dep_Pool);
00120
00121 V_STACK *parent_vertices = CXX_NEW(V_STACK(&MP_Dep_Pool),&MP_Dep_Pool);
00122 Create_Vertices(child_wn,parent_to_child,parent_vertices,parent_graph,
00123 child_graph);
00124
00125
00126 INT i;
00127 for (i=0; i<parent_vertices->Elements(); i++) {
00128 VINDEX16 parent_v = parent_vertices->Bottom_nth(i);
00129 VINDEX16 child_v = parent_to_child->Find(parent_v);
00130 Is_True(child_v,("child_v missing "));
00131 EINDEX16 e;
00132 while (e = parent_graph->Get_Out_Edge(parent_v)) {
00133 VINDEX16 parent_sink = parent_graph->Get_Sink(e);
00134 VINDEX16 child_sink = parent_to_child->Find(parent_sink);
00135 Is_True(child_sink,("child_sink missing "));
00136 child_graph->Add_Edge(child_v,child_sink,
00137 parent_graph->Dep(e),parent_graph->Is_Must(e));
00138
00139 parent_graph->Remove_Edge(e);
00140 }
00141 }
00142 for (i=0; i<parent_vertices->Elements(); i++) {
00143
00144
00145 VINDEX16 parent_v = parent_vertices->Bottom_nth(i);
00146 VINDEX16 child_v = parent_to_child->Find(parent_v);
00147 WN *wn = parent_graph->Get_Wn(parent_v);
00148 parent_graph->Delete_Vertex(parent_v);
00149 child_graph->Set_Wn(child_v,wn);
00150 }
00151 CXX_DELETE(parent_to_child,&MP_Dep_Pool);
00152 CXX_DELETE(parent_vertices,&MP_Dep_Pool);
00153 MEM_POOL_Pop(&MP_Dep_Pool);
00154 }
00155
00156
00157
00158 void Create_Vertices(WN *wn, VV_HASH_TABLE *parent_to_child,
00159 V_STACK *parent_vertices,
00160 ARRAY_DIRECTED_GRAPH16 *parent_graph,
00161 ARRAY_DIRECTED_GRAPH16 *child_graph)
00162 {
00163 OPCODE opcode = WN_opcode(wn);
00164 if (opcode == OPC_BLOCK) {
00165 WN *kid = WN_first (wn);
00166 while (kid) {
00167 Create_Vertices(kid,parent_to_child,parent_vertices,parent_graph,
00168 child_graph);
00169 kid = WN_next(kid);
00170 }
00171 return;
00172 }
00173 if (OPCODE_is_load(opcode) || OPCODE_is_store(opcode)
00174 || OPCODE_is_call(opcode)) {
00175 VINDEX16 parent_v = parent_graph->Get_Vertex(wn);
00176 if (parent_v) {
00177
00178
00179 VINDEX16 child_v = child_graph->Add_Vertex(wn);
00180 parent_to_child->Enter(parent_v,child_v);
00181 parent_vertices->Push(parent_v);
00182 }
00183 }
00184 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00185 Create_Vertices(WN_kid(wn,kidno),parent_to_child,parent_vertices,
00186 parent_graph,child_graph);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 static WN *Find_Non_POD_Finalization_Code(WN *wn, WN **final_if_parent);
00226 static void Move_Non_POD_Finalization_Code_Rec(WN *wn);
00227 static void Find_And_Move_Finalization_Code(WN *parent, WN *do_wn);
00228
00229 void Move_Non_POD_Finalization_Code(WN *block)
00230 {
00231 Is_True(block && WN_operator(block) == OPR_BLOCK, ("bad block"));
00232 Move_Non_POD_Finalization_Code_Rec(block);
00233 }
00234
00235
00236 static void Move_Non_POD_Finalization_Code_Rec(WN *wn)
00237 {
00238 Is_True(wn, ("NULL wn"));
00239 Is_True(WN_operator(wn) != OPR_DO_LOOP, ("recursed into a DO loop"));
00240
00241 if (WN_operator(wn) == OPR_BLOCK) {
00242 for (WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
00243 if (WN_operator(stmt) == OPR_DO_LOOP)
00244 Find_And_Move_Finalization_Code(wn, stmt);
00245 else
00246 Move_Non_POD_Finalization_Code_Rec(stmt);
00247 }
00248
00249 } else {
00250 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++)
00251 Move_Non_POD_Finalization_Code_Rec(WN_kid(wn, kidno));
00252 }
00253 }
00254
00255 static void Find_And_Move_Finalization_Code(WN *parent, WN *do_wn)
00256 {
00257 Is_True(parent && WN_operator(parent) == OPR_BLOCK, ("bad parent"));
00258 Is_True(do_wn && WN_operator(do_wn) == OPR_DO_LOOP, ("bad do_wn"));
00259
00260 WN *final_if, *final_if_parent, *do_body = WN_do_body(do_wn);
00261
00262 final_if = Find_Non_POD_Finalization_Code(do_body, &final_if_parent);
00263
00264 if (!final_if)
00265 return;
00266
00267
00268 WN *bar1 = WN_prev(final_if), *bar2 = WN_next(final_if),
00269 *then = WN_then(final_if), *bar3 = WN_first(then),
00270 *bar4 = WN_last(then);
00271 Is_True(bar1 && WN_operator(bar1) == OPR_FORWARD_BARRIER,
00272 ("bad bar1"));
00273 Is_True(bar2 && WN_operator(bar2) == OPR_BACKWARD_BARRIER,
00274 ("bad bar2"));
00275 Is_True(bar3 && WN_operator(bar3) == OPR_BACKWARD_BARRIER,
00276 ("bad bar3"));
00277 Is_True(bar4 && WN_operator(bar4) == OPR_FORWARD_BARRIER,
00278 ("bad bar4"));
00279 WN_DELETE_FromBlock(final_if_parent, bar1);
00280 WN_DELETE_FromBlock(final_if_parent, bar2);
00281 WN_DELETE_FromBlock(then, bar3);
00282 WN_DELETE_FromBlock(then, bar4);
00283
00284
00285 WN_EXTRACT_FromBlock(final_if_parent, final_if);
00286 WN *final_code = WN_then(final_if);
00287 WN_then(final_if) = NULL;
00288 WN_DELETE_Tree(final_if);
00289 WN_INSERT_BlockAfter(parent, do_wn, final_code);
00290 }
00291
00292
00293 static WN *Find_Non_POD_Finalization_Code(WN *wn, WN **final_if_parent)
00294 {
00295 Is_True(wn, ("NULL wn"));
00296 if (WN_operator(wn) == OPR_BLOCK) {
00297
00298
00299 for (WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
00300 BOOL first_and_last;
00301 if (Is_Nonpod_Finalization_IF(stmt, &first_and_last)) {
00302 *final_if_parent = wn;
00303 return stmt;
00304 }
00305
00306 if (WN_operator(stmt) == OPR_REGION &&
00307 WN_first(WN_region_pragmas(stmt)) &&
00308 WN_pragma(WN_first(WN_region_pragmas(stmt))) == WN_PRAGMA_PDO_BEGIN)
00309 continue;
00310
00311
00312 WN *retval = Find_Non_POD_Finalization_Code(stmt, final_if_parent);
00313 if (retval)
00314 return retval;
00315 }
00316
00317 } else {
00318 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00319 WN *retval = Find_Non_POD_Finalization_Code(WN_kid(wn, kidno),
00320 final_if_parent);
00321 if (retval)
00322 return retval;
00323 }
00324 }
00325
00326 return NULL;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335 static WN * Copy_Non_MP_Tree_Rec ( WN * tree , V_STACK *mp_vertices,
00336 VV_HASH_TABLE *mp_to_nonmp);
00337
00338 WN * Copy_Non_MP_Tree( WN * tree )
00339 {
00340 V_STACK *mp_vertices=0;
00341 VV_HASH_TABLE *mp_to_nonmp = 0;
00342 if (Current_Dep_Graph) {
00343 if (!mp_dep_pool_initialized) {
00344 MEM_POOL_Initialize(&MP_Dep_Pool,"MP_Dep_Pool",FALSE);
00345 mp_dep_pool_initialized = TRUE;
00346 }
00347 MEM_POOL_Push(&MP_Dep_Pool);
00348 mp_vertices = CXX_NEW(V_STACK(&MP_Dep_Pool),&MP_Dep_Pool);
00349 mp_to_nonmp = CXX_NEW(VV_HASH_TABLE(200,&MP_Dep_Pool),&MP_Dep_Pool);
00350 }
00351 WN *result = Copy_Non_MP_Tree_Rec(tree,mp_vertices,mp_to_nonmp);
00352
00353
00354 if (Current_Dep_Graph) {
00355 for (INT i=0; i<mp_vertices->Elements(); i++) {
00356 VINDEX16 mp_v = mp_vertices->Bottom_nth(i);
00357 VINDEX16 nonmp_v = mp_to_nonmp->Find(mp_v);
00358 Is_True(nonmp_v,("nonmp_v missing "));
00359 EINDEX16 e = Current_Dep_Graph->Get_Out_Edge(mp_v);
00360 while (e) {
00361 VINDEX16 mp_sink = Current_Dep_Graph->Get_Sink(e);
00362 VINDEX16 nonmp_sink = mp_to_nonmp->Find(mp_sink);
00363 Is_True(nonmp_sink,("nonmp_sink missing "));
00364 if ((nonmp_v != nonmp_sink) || !
00365 Current_Dep_Graph->Get_Edge(nonmp_v,nonmp_v)) {
00366 if (!Current_Dep_Graph->Add_Edge(nonmp_v,nonmp_sink,
00367 Current_Dep_Graph->Dep(e),Current_Dep_Graph->Is_Must(e))) {
00368 Current_Dep_Graph->Erase_Graph();
00369 Current_Dep_Graph = NULL;
00370 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
00371 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
00372
00373 return result;
00374 }
00375 }
00376 e = Current_Dep_Graph->Get_Next_Out_Edge(e);
00377 }
00378 }
00379 }
00380 return result;
00381 }
00382
00383 static WN * Copy_Non_MP_Tree_Rec ( WN * tree , V_STACK *mp_vertices,
00384 VV_HASH_TABLE *mp_to_nonmp)
00385 {
00386 INT32 kidno;
00387 ST *lock_st;
00388 WN *new_wn;
00389 WN *kid;
00390 WN *prev_kid;
00391 WN *next_kid;
00392 WN *new_kid;
00393 #define STACK_CHUNK 10
00394 INT32 *spr_stack = NULL;
00395
00396
00397
00398
00399 WN **kid_stack = NULL;
00400 INT32 kptr = 0;
00401 INT32 kptr_max = 0;
00402 ST **lock_stack = NULL;
00403 INT32 lptr = 0;
00404 INT32 lptr_max = 0;
00405
00406
00407
00408 BOOL must_move_non_pod = FALSE;
00409
00410 if (tree == NULL)
00411 return (NULL);
00412
00413 #ifdef Is_True_On
00414 if (WN_opcode(tree) == OPC_REGION) {
00415 RID *rid = REGION_get_rid(tree);
00416 Is_True(rid != NULL, ("Copy_Non_MP_Tree_Rec, NULL rid"));
00417 }
00418 #endif
00419
00420 new_wn = WN_CopyNode (tree);
00421
00422 if (Current_Dep_Graph) {
00423 VINDEX16 mp_v = Current_Dep_Graph->Get_Vertex(tree);
00424 if (mp_v) {
00425 VINDEX16 nonmp_v = Current_Dep_Graph->Add_Vertex(new_wn);
00426 if (!nonmp_v) {
00427 Current_Dep_Graph->Erase_Graph();
00428 Current_Dep_Graph = NULL;
00429 } else {
00430 mp_vertices->Push(mp_v);
00431 mp_to_nonmp->Enter(mp_v,nonmp_v);
00432 }
00433 }
00434 }
00435
00436 if (WN_opcode(tree) == OPC_BLOCK) {
00437
00438 prev_kid = new_kid = NULL;
00439 for (kid = WN_first(tree); kid; kid = next_kid) {
00440 next_kid = WN_next(kid);
00441 if (((WN_opcode(kid) == OPC_PRAGMA) ||
00442 (WN_opcode(kid) == OPC_XPRAGMA)) &&
00443 (WN_pragmas[WN_pragma(kid)].users & PUSER_MP)) {
00444
00445
00446 if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
00447 if ((WN_opcode(kid) == OPC_XPRAGMA) &&
00448 (WN_operator(WN_kid0(kid)) == OPR_LDA))
00449 lock_st = WN_st(WN_kid0(kid));
00450 else if ((WN_opcode(kid) == OPC_PRAGMA) && WN_st(kid))
00451 lock_st = WN_st(kid);
00452 else
00453 lock_st = NULL;
00454 if (lptr == lptr_max) {
00455 lock_stack = (ST**) MEM_POOL_Realloc (Malloc_Mem_Pool, lock_stack,
00456 sizeof(ST*)*lptr_max,
00457 sizeof(ST*)*(lptr_max+STACK_CHUNK));
00458 lptr_max += STACK_CHUNK;
00459 }
00460 lock_stack[lptr++] = lock_st;
00461 if (lock_st)
00462 new_kid = Gen_MP_Getlock ( lock_st );
00463 else
00464 new_kid = Gen_MP_Setlock ( );
00465 WN_prev(new_kid) = prev_kid;
00466 if (prev_kid)
00467 WN_next(prev_kid) = new_kid;
00468 else
00469 WN_first(new_wn) = new_kid;
00470 prev_kid = new_kid;
00471 } else if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_END) {
00472 lock_st = lock_stack[--lptr];
00473 if (lock_st)
00474 new_kid = Gen_MP_Unlock ( lock_st );
00475 else
00476 new_kid = Gen_MP_Unsetlock ( );
00477 WN_prev(new_kid) = prev_kid;
00478 if (prev_kid)
00479 WN_next(prev_kid) = new_kid;
00480 else
00481 WN_first(new_wn) = new_kid;
00482 prev_kid = new_kid;
00483 }
00484 }
00485 else if ((WN_opcode(kid) == OPC_REGION) &&
00486 WN_first(WN_region_pragmas(kid)) &&
00487 (WN_pragmas[WN_pragma(WN_first(WN_region_pragmas(kid)))].users
00488 & PUSER_MP)) {
00489
00490 WN_PRAGMA_ID pragma =
00491 (WN_PRAGMA_ID) WN_pragma(WN_first(WN_region_pragmas(kid)));
00492 if (kptr == kptr_max) {
00493 kid_stack = (WN**) MEM_POOL_Realloc (Malloc_Mem_Pool, kid_stack,
00494 sizeof(WN*) * kptr_max,
00495 sizeof(WN*) * (kptr_max+STACK_CHUNK));
00496 spr_stack = (INT32*) MEM_POOL_Realloc (Malloc_Mem_Pool, spr_stack,
00497 sizeof(INT32)*kptr_max,
00498 sizeof(INT32)*(kptr_max+STACK_CHUNK));
00499 kptr_max += STACK_CHUNK;
00500 }
00501
00502 spr_stack[kptr] = 0;
00503 if (WN_pragma_omp(WN_first(WN_region_pragmas(kid))) &&
00504 (pragma == WN_PRAGMA_DOACROSS ||
00505 pragma == WN_PRAGMA_PARALLEL_DO ||
00506 pragma == WN_PRAGMA_PARALLEL_BEGIN)) {
00507
00508 MP_process_type mpt = (pragma == WN_PRAGMA_PARALLEL_BEGIN ?
00509 MPP_PARALLEL_REGION :
00510 MPP_PARALLEL_DO);
00511 new_kid = Gen_OMP_Begin_SPR(mpt);
00512 WN_prev(new_kid) = prev_kid;
00513 if (prev_kid)
00514 WN_next(prev_kid) = new_kid;
00515 else
00516 WN_first(new_wn) = new_kid;
00517 prev_kid = new_kid;
00518 spr_stack[kptr] = (mpt == MPP_PARALLEL_REGION ? 1 : 2);
00519 } else if (WN_pragma_omp(WN_first(WN_region_pragmas(kid))) &&
00520 pragma == WN_PRAGMA_PDO_BEGIN) {
00521 must_move_non_pod = TRUE;
00522 }
00523
00524 kid_stack[kptr++] = next_kid;
00525 next_kid = WN_first(WN_region_body(kid));
00526 } else {
00527
00528 new_kid = Copy_Non_MP_Tree_Rec ( kid, mp_vertices,mp_to_nonmp );
00529 WN_prev(new_kid) = prev_kid;
00530 if (prev_kid)
00531 WN_next(prev_kid) = new_kid;
00532 else
00533 WN_first(new_wn) = new_kid;
00534 prev_kid = new_kid;
00535
00536
00537 if (WN_opcode(kid) == OPC_REGION) {
00538 RID *rid = REGION_get_rid(kid);
00539 if (!RID_TYPE_mp(rid)) {
00540
00541
00542 mUINT32 new_region_id = WN_region_id(new_kid);
00543 mUINT32 old_region_id = WN_region_id(kid);
00544
00545 WN_set_region_id(new_kid, WN_region_id(kid));
00546 REGION_new_wn(new_kid, kid);
00547 WN_set_region_id(kid, New_Region_Id());
00548 REGION_clone(new_kid, kid, NULL);
00549 }
00550
00551 }
00552 }
00553 if ((next_kid == NULL) && kptr) {
00554 if (spr_stack[kptr-1] != 0) {
00555
00556 new_kid = Gen_OMP_End_SPR(spr_stack[kptr-1] == 1?
00557 MPP_PARALLEL_REGION :
00558 MPP_PARALLEL_DO);
00559 WN_prev(new_kid) = prev_kid;
00560 if (prev_kid)
00561 WN_next(prev_kid) = new_kid;
00562 else
00563 WN_first(new_wn) = new_kid;
00564 prev_kid = new_kid;
00565 }
00566
00567 next_kid = kid_stack[--kptr];
00568 }
00569
00570 }
00571
00572 if (new_kid)
00573 WN_next(new_kid) = NULL;
00574 else
00575 WN_first(new_wn) = NULL;
00576 WN_last(new_wn) = new_kid;
00577
00578 if (must_move_non_pod)
00579 Move_Non_POD_Finalization_Code(new_wn);
00580
00581 }
00582 else {
00583
00584 for (kidno = 0; kidno < WN_kid_count(tree); kidno++) {
00585 kid = WN_kid(tree, kidno);
00586 if (kid)
00587 WN_kid(new_wn, kidno) = Copy_Non_MP_Tree_Rec ( kid, mp_vertices,
00588 mp_to_nonmp );
00589 else
00590 WN_kid(new_wn, kidno) = NULL;
00591 }
00592
00593 }
00594
00595 if (lock_stack) MEM_POOL_FREE (Malloc_Mem_Pool, lock_stack);
00596 if (kid_stack) MEM_POOL_FREE (Malloc_Mem_Pool, kid_stack);
00597 if (spr_stack) MEM_POOL_FREE (Malloc_Mem_Pool, spr_stack);
00598 return (new_wn);
00599 }