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 #define __STDC_LIMIT_MACROS
00044 #include <stdint.h>
00045 #ifdef USE_PCH
00046 #include "be_com_pch.h"
00047 #endif
00048 #pragma hdrstop
00049
00050
00051
00052
00053 #include <sys/types.h>
00054 #if defined(BUILD_OS_DARWIN)
00055 #include <darwin_elf.h>
00056 #else
00057 #include <elf.h>
00058 #endif
00059
00060 #define USE_STANDARD_TYPES
00061
00062 #include <bstring.h>
00063 #include "wn.h"
00064 #include "wn_util.h"
00065 #include "erglob.h"
00066 #include "errors.h"
00067 #include "strtab.h"
00068 #include "symtab.h"
00069 #include "irbdata.h"
00070 #include "dwarf_DST_mem.h"
00071 #include "pu_info.h"
00072 #ifdef __MINGW32__
00073 #include <WINDOWS.h>
00074 #endif
00075 #include "ir_bwrite.h"
00076 #include "ir_reader.h"
00077 #include "ir_bcom.h"
00078 #include "region_util.h"
00079 #include "dep_graph.h"
00080 #include "cxx_hash.h"
00081 #include "wn_mp.h"
00082
00083
00084
00085
00086
00087 #include <string.h>
00088
00089 #if ! defined(BUILD_OS_DARWIN)
00090 #include <elf.h>
00091 #endif
00092 #include "alloca.h"
00093 #include "cxx_template.h"
00094 #include "defs.h"
00095 #include "glob.h"
00096 #include "errors.h"
00097 #include "erglob.h"
00098 #include "erbe.h"
00099 #include "tracing.h"
00100 #include "strtab.h"
00101
00102 #include "symtab.h"
00103
00104 #include "wn.h"
00105 #include "wn_util.h"
00106 #include "wn_simp.h"
00107 #include "stblock.h"
00108 #include "data_layout.h"
00109 #include "targ_sim.h"
00110 #include "targ_const.h"
00111 #include "config_targ.h"
00112 #include "config_asm.h"
00113 #include "const.h"
00114 #include "ttype.h"
00115 #include "wn_pragmas.h"
00116 #include "wn_lower.h"
00117 #include "region_util.h"
00118 #include "wutil.h"
00119 #include "wn_map.h"
00120 #include "pu_info.h"
00121 #include "dwarf_DST.h"
00122 #include "dwarf_DST_producer.h"
00123 #include "dwarf_DST_mem.h"
00124 #include "config.h"
00125 #include "standardize.h"
00126 #include "irbdata.h"
00127 #include "omp_lower.h"
00128 #include "privatize_common.h"
00129 #include "cxx_hash.h"
00130 #include "wn_mp.h"
00131 #include "mempool.h"
00132 #include "parmodel.h"
00133 #include "fb_info.h"
00134 #include "fb_whirl.h"
00135 #include "be_symtab.h"
00136 #ifdef KEY
00137 #include "wn_lower.h"
00138 #include "config_opt.h"
00139 #endif
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #define WN_Compare_Trees(x,y) (WN_Simp_Compare_Trees(x,y))
00163
00164 static DST_INFO_IDX nested_dst;
00165 #ifdef KEY
00166 static void
00167 Transfer_Maps ( WN_MAP_TAB * parent, WN_MAP_TAB * child, WN * tree,
00168 RID * root_rid );
00169 #endif
00170
00171
00172
00173 void csc_printf(const char *what, INT line)
00174 {
00175 printf("csc: %s at wn_mp.cxx: %d .\n", what, line );
00176 }
00177
00178 #define csc_debug(x) csc_printf(x,__LINE__)
00179
00180 inline WN_OFFSET WN_offsetx ( WN *wn )
00181 {
00182 OPERATOR opr;
00183 opr = WN_operator(wn);
00184 if ((opr == OPR_PRAGMA) || (opr == OPR_XPRAGMA)) {
00185 return (WN_pragma_arg1(wn));
00186 } else {
00187 return (WN_offset(wn));
00188 }
00189 }
00190
00191 inline void WN_set_offsetx ( WN *wn, WN_OFFSET ofst )
00192 {
00193 OPERATOR opr;
00194 opr = WN_operator(wn);
00195 if ((opr == OPR_PRAGMA) || (opr == OPR_XPRAGMA)) {
00196 WN_pragma_arg1(wn) = ofst;
00197 } else {
00198 WN_offset(wn) = ofst;
00199 }
00200 }
00201
00202 static inline TYPE_ID Promote_Type(TYPE_ID mtype)
00203 {
00204 switch (mtype) {
00205 case MTYPE_I1 : case MTYPE_I2: return(MTYPE_I4);
00206 case MTYPE_U1 : case MTYPE_U2: return(MTYPE_U4);
00207 default: return mtype;
00208 }
00209 }
00210
00211 static void
00212 my_Get_Return_Pregs(PREG_NUM *rreg1, PREG_NUM *rreg2, mTYPE_ID type,
00213 const char *file, INT line)
00214 {
00215 if (WHIRL_Return_Info_On) {
00216 RETURN_INFO return_info = Get_Return_Info(Be_Type_Tbl(type),
00217 Use_Simulated);
00218 if (RETURN_INFO_count(return_info) <= 2) {
00219 *rreg1 = RETURN_INFO_preg(return_info, 0);
00220 *rreg2 = RETURN_INFO_preg(return_info, 1);
00221 } else
00222 Fail_FmtAssertion("file %s, line %d: more than 2 return registers",
00223 file, line);
00224
00225 } else
00226 Get_Return_Pregs(type, MTYPE_UNKNOWN, rreg1, rreg2);
00227
00228 FmtAssert(*rreg1 != 0 && *rreg2 == 0, ("bad return pregs"));
00229 }
00230
00231 #define GET_RETURN_PREGS(rreg1, rreg2, type) \
00232 my_Get_Return_Pregs(&rreg1, &rreg2, type, __FILE__, __LINE__)
00233
00234 typedef enum {
00235
00236 MPRUNTIME_NONE = 0,
00237 MPRUNTIME_FIRST = 1,
00238
00239 MPR_SETUP = 1,
00240 MPR_CLEANUP = 2,
00241
00242 MPR_GETLOCK = 3,
00243 MPR_UNLOCK = 4,
00244 MPR_BARRIER = 5,
00245 MPR_SETLOCK = 6,
00246 MPR_UNSETLOCK = 7,
00247
00248 MPR_COPYIN = 8,
00249
00250 MPR_PARALLEL_DO_32 = 9,
00251 MPR_PARALLEL_DO_64 = 10,
00252 MPR_PARALLEL_REGION = 11,
00253
00254 MPR_BEGIN_PDO_32 = 12,
00255 MPR_BEGIN_PDO_64 = 13,
00256 MPR_NEXT_ITERS_32 = 14,
00257 MPR_NEXT_ITERS_64 = 15,
00258 MPR_END_PDO = 16,
00259
00260 MPR_BEGIN_SINGLE_PROCESS = 17,
00261 MPR_END_SINGLE_PROCESS = 18,
00262
00263 MPR_ENTER_GATE = 19,
00264 MPR_EXIT_GATE = 20,
00265
00266 MPR_BEGIN_INDEPENDENT = 21,
00267 MPR_END_INDEPENDENT = 22,
00268
00269 MPR_MY_THREADNUM = 23,
00270
00271 MPR_OMP_PARALLEL_REGION = 24,
00272 MPR_OMP_BEGIN_SPR = 25,
00273 MPR_OMP_END_SPR = 26,
00274 MPR_OMP_PARALLEL_DO_32 = 27,
00275 MPR_OMP_PARALLEL_DO_64 = 28,
00276
00277 MPR_OMP_BEGIN_PDO_64 = 29,
00278 MPR_OMP_NEXT_ITERS_64 = 30,
00279 MPR_OMP_END_PDO = 31,
00280
00281 MPR_OMP_BEGIN_SINGLE_PROCESS = 32,
00282 MPR_OMP_END_SINGLE_PROCESS = 33,
00283 MPR_OMP_BARRIER_OLD = 34,
00284
00285 MPR_OMP_PDO_ORDERED_BEGIN = 35,
00286 MPR_OMP_PDO_ORDERED_END = 36,
00287 MPR_OMP_ORDERED_BEGIN_OLD = 37,
00288 MPR_OMP_ORDERED_END_OLD = 38,
00289
00290 MPR_OMP_COPYIN = 39,
00291 MPR_OMP_NONPOD_COPYIN = 40,
00292 MPR_OMP_NONPOD_ARRAY_COPYIN = 41,
00293
00294
00295 MPR_OMP_IN_PARALLEL = 42,
00296 MPR_OMP_CAN_FORK = 43,
00297 MPR_OMP_SET_NUM_THREADS = 44,
00298 MPR_OMP_INIT_RTL = 45,
00299 MPR_OMP_FINI_RTL = 46,
00300
00301 MPR_OMP_SERIALIZED_PARALLEL = 47,
00302 MPR_OMP_END_SERIALIZED_PARALLEL = 48,
00303 MPR_OMP_GET_THREAD_NUM = 49,
00304 MPR_OMP_GET_NUM_THREADS = 50,
00305
00306 MPR_OMP_FORK = 51,
00307
00308 MPR_OMP_STATIC_INIT_4 = 52,
00309 MPR_OMP_STATIC_INIT_8 = 53,
00310 MPR_OMP_STATIC_FINI = 54,
00311
00312 MPR_OMP_SCHEDULER_INIT_4 = 55,
00313 MPR_OMP_SCHEDULER_INIT_8 = 56,
00314 MPR_OMP_SCHEDULER_NEXT_4 = 57,
00315 MPR_OMP_SCHEDULER_NEXT_8 = 58,
00316
00317 MPR_OMP_SINGLE = 59,
00318 MPR_OMP_END_SINGLE = 60,
00319
00320 MPR_OMP_MASTER = 61,
00321 MPR_OMP_END_MASTER = 62,
00322
00323 MPR_OMP_BARRIER = 63,
00324
00325 MPR_OMP_CRITICAL = 64,
00326 MPR_OMP_END_CRITICAL = 65,
00327 MPR_OMP_ORDERED = 66,
00328 MPR_OMP_END_ORDERED = 67,
00329
00330 MPR_OMP_FLUSH = 68,
00331 #ifdef KEY
00332 MPR_OMP_GET_THDPRV = 69,
00333 MPR_OMP_COPYIN_THDPRV = 70,
00334 MPR_OMP_COPYPRIVATE = 71,
00335
00336 MPRUNTIME_LAST = MPR_OMP_COPYPRIVATE
00337 #else
00338 MPRUNTIME_LAST = MPR_OMP_FLUSH
00339 #endif
00340
00341 } MPRUNTIME;
00342
00343
00344
00345 typedef enum {
00346 OMP_SCHED_UNKNOWN = 0,
00347 OMP_SCHED_STATIC = 1,
00348 OMP_SCHED_STATIC_EVEN = 2,
00349 OMP_SCHED_DYNAMIC = 3,
00350 OMP_SCHED_GUIDED = 4,
00351 OMP_SCHED_RUNTIME = 5,
00352
00353 OMP_SCHED_ORDERED_STATIC = 33,
00354 OMP_SCHED_ORDERED_STATIC_EVEN = 34,
00355 OMP_SCHED_ORDERED_DYNAMIC = 35,
00356 OMP_SCHED_ORDERED_GUIDED = 36,
00357 OMP_SCHED_ORDERED_RUNTIME = 37,
00358
00359 OMP_SCHED_NORMAL_FIRST = OMP_SCHED_STATIC,
00360 OMP_SCHED_NORMAL_LAST = OMP_SCHED_RUNTIME,
00361 OMP_SCHED_ORDERED_FIRST = OMP_SCHED_ORDERED_STATIC,
00362 OMP_SCHED_ORDERED_LAST = OMP_SCHED_ORDERED_RUNTIME
00363 } SCHEDULE_TYPE;
00364
00365
00366 typedef enum {
00367 PAR_FUNC_NONE = 0,
00368 PAR_FUNC_DO32,
00369 PAR_FUNC_DO64,
00370 PAR_FUNC_REGION,
00371 PAR_FUNC_LAST = PAR_FUNC_REGION
00372 } PAR_FUNC_TYPE;
00373
00374 typedef enum {
00375 VAR_NONE = 0,
00376 VAR_LASTLOCAL = 1,
00377 VAR_LOCAL = 2,
00378
00379 VAR_FIRSTPRIVATE = 3,
00380 VAR_REDUCTION_SCALAR = 4,
00381 VAR_REDUCTION_ARRAY = 5,
00382
00383
00384
00385
00386 VAR_REDUCTION_ARRAY_OMP = 6
00387 } VAR_TYPE;
00388
00389 typedef struct {
00390 VAR_TYPE vtype;
00391 TYPE_ID mtype;
00392 BOOL has_offset;
00393 BOOL is_static_array;
00394 BOOL is_dynamic_array;
00395
00396 BOOL is_last_and_firstprivate;
00397 BOOL is_non_pod;
00398
00399 TY_IDX ty;
00400 WN *vtree;
00401 WN *vtreex;
00402 ST *orig_st;
00403 WN_OFFSET orig_offset;
00404 ST *new_st;
00405 WN_OFFSET new_offset;
00406 OPERATOR reduction_opr;
00407 OPCODE reduction_opc;
00408 } VAR_TABLE;
00409
00410 typedef enum {
00411 PCLASS_UNKNOWN = 0,
00412 PCLASS_DEADIN_DEADOUT = 1,
00413 PCLASS_COPYIN_DEADOUT = 2,
00414 PCLASS_DEADIN_COPYOUT = 3,
00415 PCLASS_COPYIN_COPYOUT = 4,
00416 PCLASS_LIVEIN_DEADOUT = 5,
00417 PCLASS_DEADIN_LIVEOUT = 6,
00418 PCLASS_LIVEIN_LIVEOUT = 7
00419 } PREG_CLASS;
00420
00421 typedef struct {
00422 PREG_CLASS pclass;
00423 TYPE_ID type;
00424 BOOL preamble_store;
00425 BOOL lastlocal_list;
00426 BOOL local_list;
00427 BOOL reduction_list;
00428 BOOL shared_list;
00429 INT32 shared_flags;
00430 ST *temp;
00431 } PREG_INFO;
00432
00433 typedef LABEL_IDX LABEL_INFO_TABLE;
00434
00435 typedef ST * SHARED_TABLE;
00436
00437 typedef INT32 MPID_TABLE;
00438
00439 typedef HASH_TABLE<WN *, BOOL> WN_TO_BOOL_HASH;
00440 static const mINT32 NUM_HASH_ELEMENTS = 1021;
00441
00442
00443
00444
00445
00446
00447
00448
00449 template<class T>
00450 class BOUNDSCHECKED_VECTOR {
00451 T *array;
00452 mUINT32 size;
00453 MEM_POOL *mempool;
00454 typedef BOUNDSCHECKED_VECTOR<T> *PV;
00455 BOOL zero_is_invalid;
00456 PV *ppv;
00457 public:
00458 BOUNDSCHECKED_VECTOR(MEM_POOL *_mempool, mUINT32 _size,
00459 BOOL _zero_is_invalid = FALSE, PV *_ppv = NULL)
00460 : mempool(_mempool), size(_size), zero_is_invalid(_zero_is_invalid),
00461 ppv(_ppv) {
00462 array = CXX_NEW_ARRAY(T, size, mempool);
00463 if (ppv)
00464 *ppv = this;
00465 }
00466 T &operator[](mINT32 idx) {
00467 #ifdef Is_True_On
00468 if (idx < 0)
00469 Fail_FmtAssertion("BOUNDSCHECKED_VECTOR::operator[] : negative index "
00470 "%d", idx);
00471 if (idx == 0 && zero_is_invalid)
00472 Fail_FmtAssertion("BOUNDSCHECKED_VECTOR::operator[] : invalid zero "
00473 "index");
00474 if (idx >= size)
00475 Fail_FmtAssertion("BOUNDSCHECKED_VECTOR::operator[] : out-of-bounds "
00476 "index %d (array size is %d)", idx, size);
00477 #endif
00478 return array[idx];
00479 }
00480
00481 T &at(mINT32 idx) { return (*this)[idx]; }
00482 mUINT32 Size() const { return size; }
00483 ~BOUNDSCHECKED_VECTOR() {
00484 CXX_DELETE_ARRAY(array, mempool);
00485 if (ppv)
00486 *ppv = NULL;
00487 }
00488 };
00489
00490 static BOOL first_call = TRUE;
00491 static MEM_POOL mp_lower_pool;
00492
00493 static WN *stmt_block;
00494 static WN *serial_stmt_block;
00495 static WN *cont_nodes;
00496 static WN *do_node;
00497 static WN *replace_block;
00498 static WN *ntrip_calc;
00499 static WN *livein_block;
00500 static WN *alloca_block;
00501 static WN *copyin_block;
00502 static WN *copyout_block;
00503 static WN *firstprivate_block;
00504 static WN *liveout_block;
00505 static WN *do_prefix;
00506 static WN *do_suffix;
00507 static WN *if_preamble_block;
00508 static WN *if_postamble_block;
00509 static WN *do_preamble_block;
00510 static INT64 line_number;
00511
00512 static ST *parallel_proc;
00513 static ST *local_start;
00514 static ST *local_ntrip;
00515 static ST *thread_info;
00516 static ST *local_upper = NULL;
00517 static ST *local_lower = NULL;
00518 static ST *local_stride = NULL;
00519 static ST *last_iter;
00520 static ST *local_limit;
00521 static ST *limit_st;
00522 static WN_OFFSET limit_ofst;
00523 static ST *local_gtid;
00524 static ST *local_btid;
00525 static WN *base_node;
00526 static WN *limit_node = NULL;
00527 static WN *ntrip_node;
00528 static WN *stride_node;
00529 static WN *parallel_func;
00530 static FEEDBACK *parallel_pu_fb;
00531 static WN *reference_block;
00532 static INT32 func_level;
00533 static ST *do_index_st;
00534 static TYPE_ID do_index_type;
00535 static BOOL fast_doacross;
00536
00537 static INT32 copyin_count;
00538 static INT32 local_count;
00539
00540 static INT32 reduction_count;
00541 static INT32 shared_count;
00542 static WN *affinity_nodes;
00543 static WN *affinity_d_nodes;
00544 static WN *affinity_t_nodes;
00545 static WN *chunk_node;
00546 static WN *copyin_nodes;
00547 static WN *copyin_nodes_end;
00548 static WN *if_node;
00549 static WN *lastlocal_nodes;
00550 static WN *lastthread_node;
00551 static WN *local_nodes;
00552 static WN *firstprivate_nodes;
00553
00554
00555 static WN *non_pod_finalization_nodes;
00556
00557
00558 static BOOL non_pod_first_and_lastprivate;
00559 static WN *mpnum_node;
00560 static WN *mpsched_node;
00561 static WN *numthreads_node;
00562 static WN *ordered_node;
00563 static WN *do_order_lb = NULL;
00564 static WN *do_order_stride = NULL;
00565 static WN *reduction_nodes;
00566 static WN *shared_nodes;
00567
00568 static INT32 num_constructs;
00569 static INT32 nested_local_count;
00570
00571 static INT32 nested_reduction_count;
00572 static WN *nested_affinity_nodes;
00573 static WN *nested_affinity_d_nodes;
00574 static WN *nested_affinity_t_nodes;
00575 static WN *nested_chunk_node;
00576 static WN *nested_lastlocal_nodes;
00577 static WN *nested_lastthread_node;
00578 static WN *nested_local_nodes;
00579 static WN *nested_firstprivate_nodes;
00580
00581 static WN *nested_mpsched_node;
00582 static WN *nested_nowait_node;
00583 static WN *nested_ordered_node;
00584 static WN *nested_do_order_lb = NULL;
00585 static WN *nested_do_order_stride = NULL;
00586 static WN *nested_reduction_nodes;
00587 static WN *nested_shared_nodes;
00588
00589 static VAR_TABLE *var_table;
00590 static VAR_TABLE *nested_var_table;
00591
00592 typedef BOUNDSCHECKED_VECTOR<PREG_INFO> PREG_INFO_TABLE;
00593 PREG_INFO_TABLE *preg_info_table;
00594
00595 static LABEL_INFO_TABLE *label_info_table;
00596
00597 static SHARED_TABLE *shared_table;
00598 static MPID_TABLE *mpid_table;
00599
00600 static INT32 mpid_size = 0;
00601
00602
00603 static TY_IDX mpdo32_ty = TY_IDX_ZERO;
00604 static TY_IDX mpdo64_ty = TY_IDX_ZERO;
00605 static TY_IDX mpregion_ty = TY_IDX_ZERO;
00606
00607 static TY_IDX mpruntime_ty = TY_IDX_ZERO;
00608
00609 static ST_IDX last_pu_proc_sym = ST_IDX_ZERO;
00610 static INT32 do_id = 0;
00611 static INT32 region_id = 0;
00612 static INT32 lock_id = 0;
00613 static WN *pu_chunk_node = NULL;
00614 static WN *pu_mpsched_node = NULL;
00615
00616
00617 static ST *mpbase_st = NULL;
00618 static ST *mptrips_st = NULL;
00619 static ST *mpflags_st = NULL;
00620
00621 static BOOL pu_has_eh = FALSE;
00622
00623 static SYMTAB_IDX psymtab;
00624 static SYMTAB_IDX csymtab;
00625 static PU_Info *ppuinfo;
00626 static WN_MAP_TAB *pmaptab;
00627 static WN_MAP_TAB *cmaptab;
00628
00629 static BOOL pu_has_alloca;
00630 static BOOL pu_has_region;
00631
00632 static BOOL inside_versioning_if;
00633
00634
00635
00636
00637
00638 static BOOL comp_gen_construct;
00639
00640
00641
00642
00643
00644
00645
00646 static MP_process_type mpt;
00647
00648
00649
00650 static ST * gtid_st = NULL;
00651 static TY_IDX lock_ty_idx = TY_IDX_ZERO;
00652 static ST *old_gtid_st = NULL;
00653
00654
00655 static ST *unnamed_lock_st = NULL;
00656 static BOOL critical_lock_not_init = TRUE;
00657
00658
00659
00660 static const char *mpr_names [MPRUNTIME_LAST + 1] = {
00661 "",
00662 "__mp_setup",
00663 "__mp_cleanup",
00664 "__mp_getlock",
00665 "__mp_unlock",
00666 "__mp_barrier",
00667 "mp_setlock",
00668 "mp_unsetlock",
00669 "__mp_copyin",
00670 "__mp_parallel_do",
00671 "__mp_parallel_do_64",
00672 "__mp_region",
00673 "__mp_begin_pdo",
00674 "__mp_begin_pdo_64",
00675 "__mp_next_iters",
00676 "__mp_next_iters_64",
00677 "__mp_end_pdo",
00678 "__mp_begin_single_process",
00679 "__mp_end_single_process",
00680 "__mp_enter_gate_new",
00681 "__mp_exit_gate_new",
00682 "__mp_begin_single_process",
00683 NULL,
00684 "mp_my_threadnum",
00685 "__omp_region",
00686 "__omp_begin_spr",
00687 "__omp_end_spr",
00688 "__omp_parallel_do",
00689 "__omp_parallel_do_64",
00690 "__omp_begin_pdo_64",
00691 "__omp_next_iters_64",
00692 "__omp_end_pdo",
00693 "__omp_begin_single_process",
00694 "__omp_end_single_process",
00695 "__omp_barrier",
00696 "__omp_pdo_ordered_begin",
00697 "__omp_pdo_ordered_end",
00698 "__omp_begin_ordered",
00699 "__omp_end_ordered",
00700 "__omp_copyin",
00701 "__omp_nonpod_copyin",
00702 "__omp_nonpod_array_copyin",
00703 "__ompc_in_parallel",
00704 "__ompc_can_fork",
00705 "__ompc_set_num_threads",
00706 "__ompc_init_rtl",
00707 "__ompc_fini_rtl",
00708 "__ompc_serialized_parallel",
00709 "__ompc_end_serialized_parallel",
00710 "__ompc_get_local_thread_num",
00711 "__ompc_get_num_threads",
00712 "__ompc_fork",
00713 "__ompc_static_init_4",
00714 "__ompc_static_init_8",
00715 "__ompc_static_fini",
00716 "__ompc_scheduler_init_4",
00717 "__ompc_scheduler_init_8",
00718 "__ompc_schedule_next_4",
00719 "__ompc_schedule_next_8",
00720 "__ompc_single",
00721 "__ompc_end_single",
00722 "__ompc_master",
00723 "__ompc_end_master",
00724 "__ompc_barrier",
00725 "__ompc_critical",
00726 "__ompc_end_critical",
00727 "__ompc_ordered",
00728 "__ompc_end_ordered",
00729 "__ompc_flush",
00730 #ifdef KEY
00731 "__ompc_get_thdprv",
00732 "__ompc_copyin_thdprv",
00733 "__ompc_copyprivate",
00734 #endif
00735 };
00736
00737
00738
00739
00740
00741
00742 static ST_IDX mpr_sts [MPRUNTIME_LAST + 1] = {
00743 ST_IDX_ZERO,
00744 ST_IDX_ZERO,
00745 ST_IDX_ZERO,
00746 ST_IDX_ZERO,
00747 ST_IDX_ZERO,
00748 ST_IDX_ZERO,
00749 ST_IDX_ZERO,
00750 ST_IDX_ZERO,
00751 ST_IDX_ZERO,
00752 ST_IDX_ZERO,
00753 ST_IDX_ZERO,
00754 ST_IDX_ZERO,
00755 ST_IDX_ZERO,
00756 ST_IDX_ZERO,
00757 ST_IDX_ZERO,
00758 ST_IDX_ZERO,
00759 ST_IDX_ZERO,
00760 ST_IDX_ZERO,
00761 ST_IDX_ZERO,
00762 ST_IDX_ZERO,
00763 ST_IDX_ZERO,
00764 ST_IDX_ZERO,
00765 ST_IDX_ZERO,
00766 ST_IDX_ZERO,
00767 ST_IDX_ZERO,
00768 ST_IDX_ZERO,
00769 ST_IDX_ZERO,
00770 ST_IDX_ZERO,
00771 ST_IDX_ZERO,
00772 ST_IDX_ZERO,
00773 ST_IDX_ZERO,
00774 ST_IDX_ZERO,
00775 ST_IDX_ZERO,
00776 ST_IDX_ZERO,
00777 ST_IDX_ZERO,
00778 ST_IDX_ZERO,
00779 ST_IDX_ZERO,
00780 ST_IDX_ZERO,
00781 ST_IDX_ZERO,
00782 ST_IDX_ZERO,
00783 ST_IDX_ZERO,
00784 ST_IDX_ZERO,
00785 ST_IDX_ZERO,
00786 ST_IDX_ZERO,
00787 ST_IDX_ZERO,
00788 ST_IDX_ZERO,
00789 ST_IDX_ZERO,
00790 ST_IDX_ZERO,
00791 ST_IDX_ZERO,
00792 ST_IDX_ZERO,
00793 ST_IDX_ZERO,
00794 ST_IDX_ZERO,
00795 ST_IDX_ZERO,
00796 ST_IDX_ZERO,
00797 ST_IDX_ZERO,
00798 ST_IDX_ZERO,
00799 ST_IDX_ZERO,
00800 ST_IDX_ZERO,
00801 ST_IDX_ZERO,
00802 ST_IDX_ZERO,
00803 ST_IDX_ZERO,
00804 ST_IDX_ZERO,
00805 ST_IDX_ZERO,
00806 ST_IDX_ZERO,
00807 ST_IDX_ZERO,
00808 ST_IDX_ZERO,
00809 ST_IDX_ZERO,
00810 ST_IDX_ZERO,
00811 ST_IDX_ZERO,
00812 #ifdef KEY
00813 ST_IDX_ZERO,
00814 ST_IDX_ZERO,
00815 ST_IDX_ZERO,
00816 #endif
00817 };
00818
00819 #define MPSP_STATUS_PREG_NAME "mpsp_status"
00820 #define IS_MASTER_PREG_NAME "mp_is_master"
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 class Verify_MP_Lowered {
00835 BOOL replace_block_set;
00836 WN *replace_block_start;
00837
00838 WN *replace_block_sibling;
00839 BOOL nested_pu_set;
00840 WN *nested_pu;
00841
00842 static void Verify_No_MP(WN *tree);
00843
00844 public:
00845 Verify_MP_Lowered() : replace_block_set(FALSE), nested_pu_set(FALSE) { }
00846
00847 void Set_replace_block(WN *replace, WN *sibling) {
00848 Is_True(!replace_block_set, ("Set_replace_block() called already"));
00849 replace_block_set = TRUE;
00850 replace_block_start = replace;
00851 replace_block_sibling = sibling;
00852 }
00853
00854 void Set_nested_pu_tree(WN *pu) {
00855 Is_True(!nested_pu_set, ("Set_nested_pu_tree() called already"));
00856 nested_pu_set = TRUE;
00857 nested_pu = pu;
00858 }
00859
00860 void Set_replace_block_and_nested_pu(WN *replace, WN *sibling, WN *pu) {
00861 Is_True(!replace_block_set && !nested_pu_set,
00862 ("replace_block_start and/or nested_pu set already"));
00863 replace_block_set = TRUE;
00864 replace_block_start = replace;
00865 replace_block_sibling = sibling;
00866 nested_pu_set = TRUE;
00867 nested_pu = pu;
00868 }
00869
00870 ~Verify_MP_Lowered();
00871 };
00872
00873
00874
00875
00876
00877
00878
00879
00880 Verify_MP_Lowered::~Verify_MP_Lowered()
00881 {
00882 Is_True(replace_block_set, ("replace_block_start not set"));
00883 Is_True(nested_pu_set, ("nested_pu not set"));
00884
00885 #ifdef Is_True_On
00886 for (WN *wn = replace_block_start; wn && wn != replace_block_sibling;
00887 wn = WN_next(wn))
00888 Verify_No_MP(wn);
00889
00890 if (nested_pu)
00891 Verify_No_MP(nested_pu);
00892 #endif
00893 }
00894
00895
00896 void Verify_MP_Lowered::Verify_No_MP(WN *tree)
00897 {
00898 WN_ITER *wni = WN_WALK_TreeIter(tree);
00899
00900 for ( ; wni; wni = WN_WALK_TreeNext(wni)) {
00901 WN *wn = WN_ITER_wn(wni);
00902 OPERATOR opr = WN_operator(wn);
00903
00904 if ((opr == OPR_PRAGMA || opr == OPR_XPRAGMA) &&
00905 WN_pragmas[WN_pragma(wn)].users & PUSER_MP)
00906 Fail_FmtAssertion("Verify_MP_Lowered: unlowered MP pragma %d, "
00907 "node %#lx, tree %#lx", WN_pragma(wn), (unsigned long) wn,
00908 (unsigned long) tree);
00909
00910 if (opr == OPR_IF && WN_Is_If_MpVersion(wn))
00911 Fail_FmtAssertion("Verify_MP_Lowered: unlowered MP IF, node %#lx, "
00912 "tree %#lx", (unsigned long) wn, (unsigned long) tree);
00913
00914 BOOL first_and_last;
00915 if (Is_Nonpod_Finalization_IF(wn, &first_and_last))
00916 Fail_FmtAssertion("Verify_MP_Lowered: unlowered non-POD finalization "
00917 "IF, node %#lx, tree %#lx",
00918 (unsigned long) wn, (unsigned long) tree);
00919 }
00920 }
00921
00922 Verify_MP_Lowered *verify_mp_lowered_ptr;
00923
00924
00925
00926
00927 static WN * Gen_MP_Load_Store ( ST * from_st, WN_OFFSET from_offset,
00928 ST * to_st, WN_OFFSET to_offset,
00929 BOOL is_dynamic );
00930
00931 static BOOL Is_NameLock_ST(ST *st);
00932
00933 ST_IDX Make_MPRuntime_ST ( MPRUNTIME rop );
00934
00935 #define GET_MPRUNTIME_ST(x) (mpr_sts[x] == ST_IDX_ZERO ? \
00936 Make_MPRuntime_ST(x) : mpr_sts[x])
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 class Linenum_Pusher {
00947 INT64 old_line_number;
00948 public:
00949 Linenum_Pusher(INT64 new_line_number) {
00950 if (new_line_number <= 0)
00951 Fail_FmtAssertion(
00952 "Linenum_Pusher::Linenum_Pusher() : invalid line number %lld",
00953 new_line_number);
00954 old_line_number = line_number;
00955 line_number = new_line_number;
00956
00957 }
00958 ~Linenum_Pusher() { line_number = old_line_number; }
00959 };
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 static ST *
00973 Create_Gtid_ST( void )
00974 {
00975 if( local_gtid != NULL)
00976 return local_gtid;
00977
00978 local_gtid = New_ST(CURRENT_SYMTAB);
00979 ST_Init(local_gtid, Save_Str("__ompv_gtid_s1"), CLASS_VAR, SCLASS_AUTO,
00980 EXPORT_LOCAL, MTYPE_To_TY(MTYPE_I4));
00981 return local_gtid;
00982 }
00983
00984
00985
00986
00987 static WN *
00988 Get_Gtid(ST * gtid)
00989 {
00990
00991
00992 if( gtid == NULL)
00993 {
00994 return WN_CreateIntconst( OPC_I4INTCONST, 0);
00995 }
00996 else
00997 {
00998 return WN_Ldid( MTYPE_I4, 0, gtid, ST_type( gtid ));
00999 }
01000 }
01001
01002
01003
01004
01005
01006 #ifdef TARG_MIPS
01007 #if defined(TARG_SL)
01008 BOOL Is_Target_32bit()
01009 {
01010 return TRUE;
01011 }
01012 #else
01013 BOOL Is_Target_32bit ()
01014 {
01015 return (Target_ABI == ABI_N32);
01016 }
01017 #endif
01018 #endif
01019
01020 static void
01021 Create_Lock_Type()
01022 {
01023 if( lock_ty_idx != TY_IDX_ZERO )
01024 return;
01025 #ifdef KEY
01026 #ifdef TARG_X8664
01027 if (Is_Target_32bit())
01028 lock_ty_idx = MTYPE_To_TY(MTYPE_I4);
01029 else
01030 #endif
01031 lock_ty_idx = MTYPE_To_TY(MTYPE_I8);
01032 #else
01033
01034 TY& ty = New_TY(lock_ty_idx);
01035 TY_Init(ty, 8*TY_size(MTYPE_To_TY(MTYPE_I4)), KIND_ARRAY,
01036 MTYPE_UNKNOWN, Save_Str("NAME_LOCK_TY"));
01037 Set_TY_etype(ty, Be_Type_Tbl(MTYPE_I4));
01038
01039 ARB_HANDLE arb = New_ARB();
01040 ARB_Init(arb, 0, 7, 1);
01041 Set_ARB_dimension(arb,1);
01042 Set_ARB_first_dimen(arb);
01043 Set_ARB_last_dimen(arb);
01044 Set_ARB_const_lbnd(arb);
01045 Set_ARB_lbnd_val(arb, 0);
01046 Set_ARB_const_ubnd(arb);
01047 Set_ARB_ubnd_val(arb, 7);
01048 Set_ARB_const_stride(arb);
01049 Set_ARB_stride_val(arb, 1);
01050
01051 Set_TY_arb(ty, arb);
01052 Set_TY_align(lock_ty_idx, 8*TY_size(MTYPE_To_TY(MTYPE_I4)));
01053 #endif
01054 }
01055
01056
01057
01058
01059
01060
01061 static WN *
01062 Gen_In_Parallel(void)
01063 {
01064 WN *wn = WN_Create(OPC_I4CALL, 0);
01065 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_IN_PARALLEL);
01066
01067 WN_Set_Call_Non_Data_Mod(wn);
01068 WN_Set_Call_Non_Data_Ref(wn);
01069 WN_Set_Call_Non_Parm_Mod(wn);
01070 WN_Set_Call_Parm_Ref(wn);
01071 WN_linenum(wn) = line_number;
01072
01073 return wn;
01074 }
01075
01076
01077
01078
01079
01080
01081 static WN *
01082 Gen_Can_Fork(void)
01083 {
01084 WN *wn = WN_Create(OPC_I4CALL, 0);
01085 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_CAN_FORK);
01086
01087 WN_Set_Call_Non_Data_Mod(wn);
01088 WN_Set_Call_Non_Data_Ref(wn);
01089 WN_Set_Call_Non_Parm_Mod(wn);
01090 WN_Set_Call_Parm_Ref(wn);
01091 WN_linenum(wn) = line_number;
01092
01093 return wn;
01094 }
01095
01096
01097
01098
01099
01100 static WN *
01101 Gen_Set_Num_Threads( ST * gtid, WN *nThreads)
01102 {
01103 WN *wn = WN_Create(OPC_VCALL, 2);
01104 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_SET_NUM_THREADS);
01105
01106 WN_Set_Call_Non_Data_Mod(wn);
01107 WN_Set_Call_Non_Data_Ref(wn);
01108 WN_Set_Call_Non_Parm_Mod(wn);
01109 WN_Set_Call_Parm_Ref(wn);
01110 WN_linenum(wn) = line_number;
01111
01112 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01113 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01114 WN_kid(wn, 1) = WN_CreateParm(MTYPE_I4, nThreads, Be_Type_Tbl(MTYPE_I4),
01115 WN_PARM_BY_VALUE);
01116
01117 return wn;
01118 }
01119
01120
01121
01122
01123
01124
01125 static WN *
01126 Gen_Fork (ST *proc, WN *nThreads)
01127 {
01128 WN * wn;
01129 WN * wnx;
01130 wn = WN_Create(OPC_VCALL, 3 );
01131 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_FORK);
01132
01133 WN_Set_Call_Non_Data_Mod(wn);
01134 WN_Set_Call_Non_Data_Ref(wn);
01135 WN_Set_Call_Non_Parm_Mod(wn);
01136 WN_Set_Call_Non_Parm_Ref(wn);
01137 WN_Set_Call_Parm_Ref(wn);
01138 WN_linenum(wn) = line_number;
01139
01140 if (nThreads != NULL)
01141 {
01142
01143 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, nThreads,
01144 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01145 }
01146 else
01147 {
01148
01149 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, WN_Intconst (MTYPE_I4, 0),
01150 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01151 }
01152
01153 wnx = WN_Lda( Pointer_type, 0, proc);
01154 WN_kid(wn, 1) = WN_CreateParm(Pointer_type, wnx,
01155 WN_ty(wnx), WN_PARM_BY_REFERENCE);
01156 WN *link = WN_LdidPreg( Pointer_type, Frame_Pointer_Preg_Offset);
01157 WN_kid(wn, 2) = WN_CreateParm(Pointer_type, link, WN_ty(link),
01158 WN_PARM_BY_REFERENCE);
01159
01160 return wn;
01161 }
01162
01163
01164
01165
01166
01167 static WN *
01168 Gen_Init_RTL ()
01169 {
01170 WN *wn = WN_Create(OPC_VCALL, 0);
01171 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_INIT_RTL);
01172
01173 WN_Set_Call_Non_Data_Mod(wn);
01174 WN_Set_Call_Non_Data_Ref(wn);
01175 WN_Set_Call_Non_Parm_Mod(wn);
01176 WN_Set_Call_Parm_Ref(wn);
01177
01178 WN_linenum(wn) = line_number;
01179
01180 return wn;
01181 }
01182
01183
01184
01185
01186
01187 static WN *
01188 Gen_Fini_RTL ()
01189 {
01190 WN *wn = WN_Create(OPC_VCALL, 0);
01191 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_FINI_RTL);
01192
01193 WN_Set_Call_Non_Data_Mod(wn);
01194 WN_Set_Call_Non_Data_Ref(wn);
01195 WN_Set_Call_Non_Parm_Mod(wn);
01196 WN_Set_Call_Parm_Ref(wn);
01197
01198 WN_linenum(wn) = line_number;
01199
01200 return wn;
01201 }
01202
01203
01204
01205
01206 static WN *
01207 Gen_Get_Thread_Num ()
01208 {
01209 WN *wn = WN_Create(OPC_I4CALL, 0);
01210 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_GET_THREAD_NUM);
01211
01212 WN_Set_Call_Non_Data_Mod(wn);
01213 WN_Set_Call_Non_Data_Ref(wn);
01214 WN_Set_Call_Non_Parm_Mod(wn);
01215 WN_Set_Call_Parm_Ref(wn);
01216 WN_linenum(wn) = line_number;
01217
01218 return wn;
01219 }
01220
01221
01222
01223
01224
01225
01226 static WN *
01227 Gen_Store_Gtid ()
01228 {
01229 WN *block = WN_CreateBlock( );
01230 if( local_gtid == NULL )
01231 {
01232 Create_Gtid_ST( );
01233 }
01234 WN *wn = Gen_Get_Thread_Num();
01235 WN_INSERT_BlockLast( block, wn );
01236 PREG_NUM rreg1, rreg2;
01237 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
01238 wn = WN_Stid( MTYPE_I4, 0, local_gtid, ST_type( local_gtid ),
01239 WN_LdidPreg ( MTYPE_I4, rreg1 ));
01240 WN_linenum(wn) = line_number;
01241 WN_INSERT_BlockLast( block, wn );
01242
01243 return block;
01244 }
01245
01246
01247
01248
01249 static WN *
01250 Set_Thread_Num( WN *nThreads )
01251 {
01252 WN *block = WN_CreateBlock();
01253 WN_INSERT_BlockLast( block, Gen_Store_Gtid());
01254 WN_INSERT_BlockLast( block,
01255 Gen_Set_Num_Threads( local_gtid, nThreads ));
01256
01257 return block;
01258 }
01259
01260
01261
01262
01263 static WN *
01264 Gen_Get_Num_Threads()
01265 {
01266 WN *wn = WN_Create(OPC_I4CALL, 0);
01267 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_GET_NUM_THREADS);
01268
01269 WN_Set_Call_Non_Data_Mod(wn);
01270 WN_Set_Call_Non_Data_Ref(wn);
01271 WN_Set_Call_Non_Parm_Mod(wn);
01272 WN_Set_Call_Parm_Ref(wn);
01273 WN_linenum(wn) = line_number;
01274
01275 return wn;
01276 }
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 #if defined(KEY) && defined(Is_True_On)
01290
01291 static BOOL serialized_parallel_in_cond = FALSE;
01292 #endif // KEY && Is_True_On
01293
01294 #ifdef KEY
01295 static WN * serial_test;
01296 #endif // KEY
01297
01298 static WN *
01299 Gen_Serialized_Parallel (ST *gtid)
01300 {
01301 #ifdef KEY
01302 WN *wn = WN_Create(OPC_VCALL, 0);
01303 #else
01304 WN *wn = WN_Create(OPC_VCALL, 1);
01305 #endif
01306 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_SERIALIZED_PARALLEL);
01307
01308 WN_Set_Call_Non_Data_Mod(wn);
01309 WN_Set_Call_Non_Data_Ref(wn);
01310 WN_Set_Call_Non_Parm_Mod(wn);
01311 WN_Set_Call_Parm_Ref(wn);
01312 WN_linenum(wn) = line_number;
01313
01314 #ifdef KEY
01315 serial_test = NULL;
01316
01317 if (if_node)
01318 {
01319 #ifdef Is_True_On
01320 Is_True (!serialized_parallel_in_cond,
01321 ("Did we forget to end our previous serialized_parallel?"));
01322
01323 serialized_parallel_in_cond = TRUE;
01324 #endif // Is_True_On
01325
01326
01327 WN * if_test = WN_COPY_Tree (WN_kid0 (if_node));
01328
01329
01330 ST * cmp = Gen_Temp_Symbol (MTYPE_TO_TY_array[WN_rtype (if_test)],
01331 "test_serial");
01332
01333 WN * blk = WN_CreateBlock ();
01334
01335
01336 WN_INSERT_BlockLast (blk, WN_Stid (WN_rtype (if_test),
01337 0,
01338 cmp,
01339 ST_type (cmp),
01340 if_test));
01341
01342
01343 serial_test = WN_Ldid (WN_rtype (if_test), 0, cmp, ST_type (cmp));
01344
01345 if_test = WN_COPY_Tree (serial_test);
01346 WN * if_then = WN_CreateBlock ();
01347 WN * if_else = WN_CreateBlock ();
01348
01349
01350 WN_INSERT_BlockLast (if_then, wn);
01351
01352 WN * if_wn = WN_CreateIf (if_test, if_then, if_else);
01353 WN_linenum (if_wn) = line_number;
01354
01355 WN_INSERT_BlockLast (blk, if_wn);
01356 return blk;
01357 }
01358 #endif // KEY
01359
01360 #ifndef KEY
01361 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01362 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01363 #endif // !KEY
01364
01365 return wn;
01366 }
01367
01368
01369
01370
01371
01372
01373 static WN *
01374 Gen_End_Serialized_Parallel( ST *gtid )
01375 {
01376 #ifdef KEY
01377 WN *wn = WN_Create(OPC_VCALL, 0);
01378 #else
01379 WN *wn = WN_Create(OPC_VCALL, 1);
01380 #endif
01381 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_END_SERIALIZED_PARALLEL);
01382
01383 WN_Set_Call_Non_Data_Mod(wn);
01384 WN_Set_Call_Non_Data_Ref(wn);
01385 WN_Set_Call_Non_Parm_Mod(wn);
01386 WN_Set_Call_Parm_Ref(wn);
01387 WN_linenum(wn) = line_number;
01388
01389 #ifdef KEY
01390 if (if_node)
01391 {
01392 #ifdef Is_True_On
01393 Is_True (serialized_parallel_in_cond,
01394 ("Did we forget to start a serialized_parallel?"));
01395
01396 serialized_parallel_in_cond = FALSE;
01397 #endif // Is_True_On
01398
01399 FmtAssert (serial_test, ("NULL compare statement"));
01400
01401 WN * if_test = WN_COPY_Tree (serial_test);
01402 WN_Delete (serial_test);
01403 serial_test = NULL;
01404
01405 WN * if_then = WN_CreateBlock ();
01406 WN * if_else = WN_CreateBlock ();
01407
01408 WN_INSERT_BlockLast (if_then, wn);
01409
01410 WN * if_wn = WN_CreateIf (if_test, if_then, if_else);
01411 WN_linenum (if_wn) = line_number;
01412 return if_wn;
01413 }
01414 #endif // KEY
01415
01416 #ifndef KEY
01417 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01418 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01419 #endif // !KEY
01420
01421 return wn;
01422 }
01423
01424 static WN *Gen_Master( ST *gtid );
01425 static void Create_Preg_or_Temp ( TYPE_ID mtype, char *name, ST **st,
01426 WN_OFFSET *ofst );
01427 static WN * Gen_MP_Load ( ST * st, WN_OFFSET offset, BOOL scalar_only = FALSE );
01428 static WN * Gen_Barrier ( ST* gtid );
01429
01430
01431
01432
01433 static WN *
01434 Gen_Critical (ST *gtid, ST *lck)
01435 {
01436 WN *wn = WN_Create(OPC_VCALL, 2);
01437 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_CRITICAL);
01438
01439 WN_Set_Call_Non_Data_Mod(wn);
01440 WN_Set_Call_Non_Data_Ref(wn);
01441 WN_Set_Call_Parm_Ref(wn);
01442 WN_Set_Call_Parm_Mod(wn);
01443 WN_linenum(wn) = line_number;
01444
01445 WN_kid(wn, 0) = WN_CreateParm( MTYPE_I4, Get_Gtid( gtid ),
01446 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
01447
01448 WN_kid(wn, 1) = WN_CreateParm( Pointer_type,
01449 WN_Lda( Pointer_type, 0, lck ),
01450 Be_Type_Tbl( Pointer_type ), WN_PARM_BY_REFERENCE );
01451
01452 WN *return_wn = NULL;
01453
01454 #ifndef KEY
01455 if( critical_lock_not_init == TRUE )
01456 {
01457 return_wn = WN_CreateBlock( );
01458
01459
01460
01461 WN *wn_master = Gen_Master( gtid);
01462 WN_linenum( wn_master ) = line_number;
01463 WN_INSERT_BlockLast( return_wn, wn_master );
01464 ST *return_st;
01465 WN_OFFSET return_ofst;
01466 PREG_NUM rreg1, rreg2;
01467 Create_Preg_or_Temp ( MTYPE_I4, "is_master", &return_st, &return_ofst );
01468 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
01469 WN *wn_temp = WN_Stid (MTYPE_I4, return_ofst, return_st, ST_type(return_st),
01470 WN_LdidPreg ( MTYPE_I4, rreg1 ));
01471 WN_linenum(wn_temp) = line_number;
01472 WN_INSERT_BlockLast( return_wn, wn_temp );
01473
01474
01475 WN *test = WN_EQ(MTYPE_I4,
01476 Gen_MP_Load( return_st, return_ofst ),
01477 WN_CreateIntconst ( OPC_I4INTCONST, 1 ));
01478 WN *if_wn = WN_CreateIf(test,WN_CreateBlock(),WN_CreateBlock());
01479 WN_linenum( if_wn ) = line_number;
01480
01481
01482
01483
01484 Create_Lock_Type( );
01485 TY_IDX ptr_lck = Make_Pointer_Type( lock_ty_idx, FALSE );
01486 WN *lck_addr = WN_Lda( Pointer_type, 0, lck );
01487
01488 WN *init_wn = WN_CreateMstore( 0, ptr_lck,
01489 WN_Intconst( MTYPE_I4, 0 ),
01490 lck_addr,
01491 WN_Intconst( MTYPE_I4, 32 ));
01492
01493 WN_linenum( init_wn ) = line_number;
01494 WN_INSERT_BlockLast( WN_then( if_wn ), init_wn );
01495
01496 WN_INSERT_BlockLast( return_wn, if_wn );
01497 WN_INSERT_BlockLast( return_wn, Gen_Barrier( gtid ));
01498 WN_INSERT_BlockLast( return_wn, wn );
01499 }
01500 else
01501 #endif
01502 return_wn = wn;
01503
01504 return return_wn;
01505 }
01506
01507
01508
01509
01510 static WN *
01511 Gen_End_Critical (ST *gtid, ST *lck)
01512 {
01513 WN *wn = WN_Create(OPC_VCALL, 2);
01514 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_END_CRITICAL);
01515
01516 WN_Set_Call_Non_Data_Mod(wn);
01517 WN_Set_Call_Non_Data_Ref(wn);
01518 WN_Set_Call_Parm_Mod(wn);
01519 WN_Set_Call_Parm_Ref(wn);
01520 WN_linenum(wn) = line_number;
01521
01522 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01523 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01524 WN_kid(wn, 1) = WN_CreateParm( Pointer_type,
01525 WN_Lda( Pointer_type, 0, lck ),
01526 Be_Type_Tbl( Pointer_type ), WN_PARM_BY_REFERENCE );
01527
01528 return wn;
01529 }
01530
01531
01532
01533
01534 static WN *
01535 Gen_Ordered( ST *gtid )
01536 {
01537 WN *wn = WN_Create(OPC_VCALL, 1);
01538 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_ORDERED);
01539
01540 WN_Set_Call_Non_Data_Mod(wn);
01541 WN_Set_Call_Non_Data_Ref(wn);
01542 WN_Set_Call_Non_Parm_Mod(wn);
01543 WN_Set_Call_Parm_Ref(wn);
01544 WN_linenum(wn) = line_number;
01545
01546 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01547 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01548
01549 return wn;
01550 }
01551
01552
01553
01554
01555 static WN *
01556 Gen_End_Ordered( ST *gtid )
01557 {
01558 WN *wn = WN_Create(OPC_VCALL, 1);
01559 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_END_ORDERED);
01560
01561 WN_Set_Call_Non_Data_Mod(wn);
01562 WN_Set_Call_Non_Data_Ref(wn);
01563 WN_Set_Call_Non_Parm_Mod(wn);
01564 WN_Set_Call_Parm_Ref(wn);
01565 WN_linenum(wn) = line_number;
01566
01567 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01568 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01569
01570 return wn;
01571 }
01572
01573
01574
01575
01576 static WN *
01577 Gen_Master (ST *gtid)
01578 {
01579 WN *wn = WN_Create(OPC_I4CALL, 1);
01580 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_MASTER);
01581
01582 WN_Set_Call_Non_Data_Mod(wn);
01583 WN_Set_Call_Non_Data_Ref(wn);
01584 WN_Set_Call_Non_Parm_Mod(wn);
01585 WN_Set_Call_Parm_Ref(wn);
01586 WN_linenum(wn) = line_number;
01587
01588 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01589 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01590
01591 return wn;
01592 }
01593
01594
01595
01596
01597 static WN *
01598 Gen_End_Master (ST *gtid)
01599 {
01600 WN *wn = WN_Create(OPC_VCALL, 1);
01601 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_END_MASTER);
01602
01603 WN_Set_Call_Non_Data_Mod(wn);
01604 WN_Set_Call_Non_Data_Ref(wn);
01605 WN_Set_Call_Non_Parm_Mod(wn);
01606 WN_Set_Call_Parm_Ref(wn);
01607 WN_linenum(wn) = line_number;
01608
01609 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01610 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01611
01612 return wn;
01613 }
01614
01615
01616
01617
01618
01619
01620 static WN *
01621 Gen_Single (WN * constructnum,
01622 ST * gtid,
01623 BOOL is_omp)
01624 {
01625 WN *wn;
01626
01627 #ifndef KEY
01628 if (is_omp)
01629 #else
01630 if (TRUE)
01631 #endif
01632 {
01633 wn = WN_Create ( OPC_I4CALL, 1 );
01634 WN_st_idx(wn) = GET_MPRUNTIME_ST ( MPR_OMP_SINGLE );
01635
01636 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01637 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01638 } else {
01639 wn = WN_Create ( OPC_I4CALL, 1 );
01640 WN_st_idx(wn) = GET_MPRUNTIME_ST ( MPR_BEGIN_SINGLE_PROCESS );
01641
01642 WN_kid(wn, 0) = WN_CreateParm (MTYPE_I4, constructnum,
01643 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01644 }
01645 WN_Set_Call_Non_Data_Mod ( wn );
01646 WN_Set_Call_Non_Data_Ref ( wn );
01647 WN_Set_Call_Non_Parm_Mod ( wn );
01648 WN_Set_Call_Non_Parm_Ref ( wn );
01649 WN_Set_Call_Parm_Ref ( wn );
01650 WN_linenum(wn) = line_number;
01651
01652 return ( wn );
01653 }
01654
01655
01656
01657
01658
01659
01660
01661 static WN *
01662 Gen_End_Single (WN * constructnum,
01663 ST * gtid,
01664 BOOL is_omp, BOOL nowait)
01665 {
01666 Is_True( is_omp || !nowait, ("no need for END_SINGLE_PROCESS runtime call"));
01667
01668 WN *return_wn = WN_CreateBlock( );
01669 WN *wn;
01670
01671 #ifndef KEY
01672 if (is_omp)
01673 #else
01674 if (TRUE)
01675 #endif
01676 {
01677 wn = WN_Create ( OPC_VCALL, 1 );
01678 WN_st_idx(wn) = GET_MPRUNTIME_ST ( MPR_OMP_END_SINGLE );
01679
01680 WN_kid(wn, 0) = WN_CreateParm(MTYPE_I4, Get_Gtid( gtid ),
01681 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE);
01682 } else {
01683 wn = WN_Create ( OPC_VCALL, 1 );
01684 WN_st_idx(wn) = GET_MPRUNTIME_ST ( MPR_END_SINGLE_PROCESS );
01685 WN_kid0(wn) = WN_CreateParm (MTYPE_I4, constructnum, Be_Type_Tbl(MTYPE_I4),
01686 WN_PARM_BY_VALUE);
01687 }
01688 WN_Set_Call_Non_Data_Mod ( wn );
01689 WN_Set_Call_Non_Data_Ref ( wn );
01690 WN_Set_Call_Non_Parm_Mod ( wn );
01691 WN_Set_Call_Non_Parm_Ref ( wn );
01692 WN_Set_Call_Parm_Ref ( wn );
01693 WN_linenum(wn) = line_number;
01694
01695 WN_INSERT_BlockLast( return_wn, wn );
01696
01697 if( is_omp && !nowait )
01698 {
01699
01700
01701
01702 WN_INSERT_BlockLast( return_wn, Gen_Barrier( gtid ));
01703 }
01704
01705 return ( return_wn );
01706 }
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723 static WN *
01724 Gen_Flush( ST *flush_var, WN_OFFSET flush_offset)
01725 {
01726 WN *wn = WN_Create(OPC_VCALL, 1);
01727 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_FLUSH);
01728
01729 WN_Set_Call_Non_Data_Mod(wn);
01730 WN_Set_Call_Non_Data_Ref(wn);
01731 WN_Set_Call_Parm_Mod(wn);
01732 WN_Set_Call_Parm_Ref(wn);
01733 WN_linenum(wn) = line_number;
01734
01735 WN_kid(wn, 0) = WN_CreateParm( Pointer_type,
01736 WN_Lda( Pointer_type, flush_offset, flush_var ),
01737 Be_Type_Tbl( Pointer_type ), WN_PARM_BY_REFERENCE );
01738
01739 return wn;
01740 }
01741 #ifdef KEY
01742 static WN*
01743 Get_First_Stmt_in_Block(WN *block)
01744 {
01745 WN *first = WN_first(block);
01746 OPERATOR opr = WN_operator( first );
01747 if ( opr == OPR_ALTENTRY ){
01748 while (opr != OPR_PRAGMA ||
01749 WN_pragma( first ) != WN_PRAGMA_PREAMBLE_END)
01750 first = WN_next(first);
01751 opr = WN_operator(first);
01752 }
01753 if (opr == OPR_PRAGMA &&
01754 WN_pragma( first ) == WN_PRAGMA_PREAMBLE_END){
01755 first = WN_next(first);
01756 opr = WN_operator(first);
01757 }
01758 if (opr == OPR_PRAGMA &&
01759 WN_pragma( first ) == WN_PRAGMA_START_STMT_CLUMP)
01760 first = WN_next(first);
01761
01762 return first;
01763 }
01764 static ST*
01765 Extract_Gtid_ST(WN *block)
01766 {
01767 WN *wn = WN_first(block);
01768 while (wn){
01769 OPERATOR opr = WN_operator(wn);
01770 if (opr == OPR_STID){
01771 if (strcmp( ST_name(WN_st(wn)), "__ompv_temp_gtid") == 0)
01772 return WN_st(wn);
01773 }
01774 wn = WN_next(wn);
01775 }
01776 return NULL;
01777 }
01778
01779 void
01780 Gen_Threadpriv_Func(WN* prags, WN* block, BOOL prepend)
01781 {
01782 WN *blck = prags;
01783 WN *keep_prags;
01784 WN *thrprv_assign;
01785 WN *wn;
01786 ST *gtid_st = NULL;
01787 BOOL need_thread_num = FALSE;
01788
01789 BOOL target_32bit = Is_Target_32bit();
01790
01791 const OPCODE uint_opc = (Pointer_Size == 4) ? OPC_U4INTCONST :
01792 (Pointer_Size == 8) ? OPC_U8INTCONST : OPCODE_UNKNOWN;
01793 const mTYPE_ID uint_mtype = (uint_opc == OPC_U4INTCONST) ? MTYPE_U4 : MTYPE_U8;
01794
01795 prags = WN_first(prags);
01796
01797 while (prags) {
01798 keep_prags = WN_next(prags);
01799 if (WN_opcode(prags) != OPC_PRAGMA ||
01800 WN_pragma(prags) != WN_PRAGMA_THREADPRIVATE) {
01801 prags = keep_prags;
01802 continue;
01803 }
01804 WN *stmt = WN_first(block);
01805 BOOL match = FALSE;
01806 while (WN_opcode(stmt) == OPC_VCALL &&
01807 WN_kid_count(stmt) == 4){
01808 if (WN_operator(WN_kid0(WN_kid2(stmt))) == OPR_LDA &&
01809 WN_st(WN_kid0(WN_kid2(stmt))) == WN_st(prags)) {
01810 match = TRUE;
01811 break;
01812 }
01813 stmt = WN_next(stmt);
01814 }
01815 if (match){
01816 prags = keep_prags;
01817 continue;
01818 }
01819
01820 wn = WN_Create(OPC_VCALL, 4);
01821 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_GET_THDPRV);
01822
01823 WN_Set_Call_Non_Data_Mod(wn);
01824 WN_Set_Call_Non_Data_Ref(wn);
01825 WN_Set_Call_Parm_Mod(wn);
01826 WN_Set_Call_Parm_Ref(wn);
01827 WN_linenum(wn) = line_number;
01828
01829 if (ST_is_not_used(ST_ptr(WN_pragma_arg2(prags))))
01830 Clear_ST_is_not_used(ST_ptr(WN_pragma_arg2(prags)));
01831 WN_kid(wn, 0) = WN_CreateParm( Pointer_type,
01832 WN_Lda( Pointer_type, 0, ST_ptr(WN_pragma_arg2(prags)) ),
01833 Be_Type_Tbl( Pointer_type ), WN_PARM_BY_REFERENCE );
01834
01835 WN_kid(wn, 1) = WN_CreateParm(MTYPE_I8,
01836 WN_Intconst (MTYPE_I8, ST_size(ST_ptr(WN_st_idx(prags)))),
01837 Be_Type_Tbl(MTYPE_I8), WN_PARM_BY_VALUE);
01838
01839 if (ST_is_not_used(WN_st(prags)))
01840 Clear_ST_is_not_used(WN_st(prags));
01841 WN_kid(wn, 2) = WN_CreateParm( Pointer_type,
01842 WN_Lda( Pointer_type, 0, ST_ptr(WN_st_idx(prags)) ),
01843 Be_Type_Tbl( Pointer_type ), WN_PARM_BY_REFERENCE );
01844
01845
01846
01847
01848 if (!gtid_st){
01849 gtid_st = New_ST(CURRENT_SYMTAB);
01850 ST_Init(gtid_st, Save_Str("__ompv_gtid_s1"), CLASS_VAR, SCLASS_AUTO,
01851 EXPORT_LOCAL, MTYPE_To_TY(MTYPE_I4));
01852 need_thread_num = TRUE;
01853 }
01854
01855 WN_kid(wn, 3) = WN_CreateParm( uint_mtype ,
01856 Gen_MP_Load(gtid_st, 0),
01857 Be_Type_Tbl( uint_mtype ), WN_PARM_BY_REFERENCE );
01858
01859 WN *thrprv_block = WN_CreateBlock ();
01860 WN_INSERT_BlockLast(thrprv_block, wn);
01861
01862 WN_OFFSET return_ofst = 0;
01863
01864 ST *local_st = ST_ptr(WN_pragma_arg1(prags));
01865 ST *global_st = ST_ptr(WN_pragma_arg2(prags));
01866 TYPE_ID type = TY_mtype(TY_pointed(ST_type(global_st)));
01867 OPCODE load_opc = OPCODE_make_op(OPR_ILOAD,Pointer_type, Pointer_type);
01868
01869 WN *test = WN_CIOR(WN_EQ(MTYPE_I4,
01870 Gen_MP_Load( ST_ptr(WN_pragma_arg2(prags)), return_ofst ),
01871 WN_CreateIntconst (target_32bit?OPC_U4INTCONST:OPC_U8INTCONST, 0)),
01872 WN_EQ(MTYPE_I4,
01873 WN_CreateIload(load_opc, 0,
01874 Be_Type_Tbl(Pointer_type),
01875 Make_Pointer_Type(Be_Type_Tbl(type),FALSE),
01876 WN_Add (uint_mtype,
01877 WN_Ldid(Pointer_type, 0,
01878 global_st,
01879 ST_type(global_st)),
01880 WN_Mpy (uint_mtype,
01881 WN_Ldid(MTYPE_I4, 0,
01882 gtid_st,
01883 ST_type(gtid_st)),
01884 WN_CreateIntconst (uint_opc,
01885 target_32bit?4:8)
01886 )
01887 )
01888 ),
01889 WN_CreateIntconst (target_32bit?OPC_U4INTCONST:OPC_U8INTCONST, 0)
01890 )
01891 );
01892 WN *thrprv_test = WN_CreateIf( test, thrprv_block, WN_CreateBlock());
01893
01894
01895
01896 thrprv_assign = WN_Stid(Pointer_type, 0,
01897 ST_ptr(WN_pragma_arg1(prags)),
01898 ST_type(local_st),
01899 WN_CreateIload(load_opc, 0,
01900 Be_Type_Tbl(Pointer_type),
01901 Make_Pointer_Type(Be_Type_Tbl(type),FALSE),
01902 WN_Add (uint_mtype,
01903 WN_Ldid(Pointer_type, 0,
01904 global_st,
01905 ST_type(global_st)),
01906 WN_Mpy (uint_mtype,
01907 WN_Ldid(MTYPE_I4, 0,
01908 gtid_st,
01909 ST_type(gtid_st)),
01910 WN_CreateIntconst (uint_opc,
01911 target_32bit?4:8)))));
01912
01913 if (prepend != TRUE) {
01914 WN_INSERT_BlockLast(block, thrprv_test);
01915 WN_INSERT_BlockLast(block, thrprv_assign);
01916 wn = NULL;
01917 }
01918 else{
01919 wn = Get_First_Stmt_in_Block(block);
01920 WN_INSERT_BlockBefore(block, wn, thrprv_test);
01921 WN_INSERT_BlockBefore(block, wn, thrprv_assign);
01922 }
01923 WN_DELETE_FromBlock(blck, prags);
01924
01925 prags = keep_prags;
01926 }
01927 if (need_thread_num){
01928 if (prepend == TRUE){
01929 if (!wn || !WN_prev(wn) || !WN_prev(WN_prev(wn)))
01930 Fail_FmtAssertion("cannot find a place to insert threadprivate");
01931 wn = WN_prev(WN_prev(wn));
01932 }
01933 else{
01934 wn = Get_First_Stmt_in_Block(block);
01935 wn = WN_next(WN_next(wn));
01936 }
01937 WN_INSERT_BlockBefore( block, wn, Gen_Get_Thread_Num() );
01938 PREG_NUM rreg1, rreg2;
01939 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
01940 WN* wnx = WN_Stid( MTYPE_I4, 0, gtid_st, ST_type( gtid_st ),
01941 WN_LdidPreg ( MTYPE_I4, rreg1 ));
01942 WN_INSERT_BlockBefore( block, wn, wnx );
01943 }
01944
01945 }
01946 #endif
01947
01948
01949
01950
01951
01952
01953 static void
01954 Push_Some_Globals( )
01955 {
01956
01957 old_gtid_st = local_gtid;
01958
01959 }
01960
01961
01962
01963
01964
01965 static void
01966 Pop_Some_Globals( )
01967 {
01968
01969
01970
01971 local_gtid = old_gtid_st;
01972 old_gtid_st = NULL;
01973
01974 }
01975
01976
01977
01978
01979
01980 static void
01981 Init_PU_Globals( )
01982 {
01983
01984 local_gtid = NULL;
01985 }
01986
01987
01988
01989
01990
01991
01992 static void
01993 Add_DST_variable ( ST *st, DST_INFO_IDX parent_dst,
01994 INT64 line_number, DST_INFO_IDX type_idx )
01995 {
01996 DST_INFO *info;
01997 DST_INFO_IDX dst, child_idx;
01998 DST_ATTR_IDX attr_idx;
01999 DST_ASSOC_INFO *assoc;
02000 DST_BASETYPE *attr;
02001 USRCPOS srcpos;
02002 INT32 typesize;
02003 static DST_INFO_IDX int32_idx = {DST_INVALID_BLOCK_IDX, DST_INVALID_BYTE_IDX};
02004 static DST_INFO_IDX int64_idx = {DST_INVALID_BLOCK_IDX, DST_INVALID_BYTE_IDX};
02005 DST_INFO_IDX int_idx;
02006 DST_IDX cmp;
02007 char *name;
02008
02009
02010 if (Debug_Level == 0)
02011 return;
02012
02013 if (DST_IS_NULL( type_idx )) {
02014
02015
02016
02017
02018 if (TY_kind(ST_type(st)) == KIND_POINTER) {
02019 typesize = TY_size(TY_pointed(ST_type(st)));
02020 } else {
02021 typesize = TY_size(ST_type(st));
02022 }
02023
02024 const char *int_name1, *int_name2, *int_name3;
02025 DST_INFO_IDX *int_idx_p;
02026
02027 switch (typesize) {
02028 case 4:
02029 int_name1 = "int"; int_name2 = "INTEGER*4"; int_name3 = "INTEGER_4";
02030 int_idx_p = &int32_idx;
02031 break;
02032 case 8:
02033 #ifndef KEY
02034 int_name1 = "long long";
02035 #else
02036
02037
02038 int_name1 = "long long int";
02039 #endif
02040 int_name2 = "INTEGER*8"; int_name3 = "INTEGER_8";
02041 int_idx_p = &int64_idx;
02042 break;
02043 default:
02044 Fail_FmtAssertion("can't handle typesize == %d", (INT) typesize);
02045 }
02046
02047 if (DST_IS_NULL(*int_idx_p) ) {
02048 cmp = DST_get_compile_unit();
02049 info = DST_INFO_IDX_TO_PTR( cmp );
02050 attr_idx = DST_INFO_attributes( info );
02051 child_idx = DST_COMPILE_UNIT_first_child(
02052 DST_ATTR_IDX_TO_PTR(attr_idx, DST_COMPILE_UNIT));
02053 while (!DST_IS_NULL(child_idx)) {
02054 info = DST_INFO_IDX_TO_PTR( child_idx );
02055 if (DST_INFO_tag( info ) == DW_TAG_base_type) {
02056 attr = DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_BASETYPE);
02057 name = DST_STR_IDX_TO_PTR( DST_FORMAL_PARAMETER_name(attr));
02058 #ifdef KEY //bug 11848: name can not be null
02059 if(name == NULL)
02060 Is_True(0, ("Base type should have a name in a DST entry"));
02061 else
02062 #endif
02063 if (!strcmp(name, int_name1) || !strcmp(name, int_name2) ||
02064 !strcmp(name, int_name3)) {
02065 *int_idx_p = child_idx;
02066 break;
02067 }
02068 }
02069 child_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(child_idx));
02070 }
02071 if (DST_IS_NULL(child_idx)) {
02072
02073 *int_idx_p = DST_mk_basetype(int_name1, DW_ATE_signed, typesize);
02074 (void) DST_append_child(parent_dst, *int_idx_p);
02075 }
02076 }
02077 int_idx = *int_idx_p;
02078
02079 }
02080
02081 USRCPOS_srcpos(srcpos) = line_number;
02082 if (ST_sclass(st) == SCLASS_FORMAL_REF) {
02083 dst = DST_mk_formal_parameter( srcpos,
02084 ST_name( st ),
02085 int_idx,
02086 ST_st_idx(st),
02087 DST_INVALID_IDX,
02088 DST_INVALID_IDX,
02089 FALSE,
02090 FALSE,
02091 FALSE,
02092 FALSE );
02093 DST_SET_deref( DST_INFO_flag( DST_INFO_IDX_TO_PTR (dst) ) );
02094 } else
02095 dst = DST_mk_variable( srcpos,
02096 ST_name( st ),
02097 int_idx,
02098 0 ,
02099 ST_st_idx(st),
02100 DST_INVALID_IDX,
02101 FALSE,
02102 TRUE,
02103 FALSE,
02104 FALSE);
02105
02106 (void)DST_append_child( parent_dst, dst );
02107 #if 0
02108 info = DST_INFO_IDX_TO_PTR( dst );
02109 assoc = &DST_VARIABLE_def_st(
02110 DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_VARIABLE));
02111 pDST_ASSOC_INFO_st_idx(assoc) = ST_st_idx(st);
02112 DST_SET_assoc_idx(DST_INFO_flag(info));
02113 DST_RESET_assoc_fe(DST_INFO_flag(info));
02114 #endif
02115 }
02116
02117
02118 extern DST_IDX
02119 Find_DST_From_ST ( ST *st, PU_Info *pu_info )
02120 {
02121 DST_INFO_IDX dst, child_idx;
02122 DST_INFO *info;
02123 INT32 level, index;
02124 DST_ASSOC_INFO *assoc;
02125 DST_DW_tag tag;
02126 DST_flag flag;
02127 DST_ATTR_IDX iattr;
02128
02129 level = ST_level(st);
02130 index = ST_index(st);
02131 dst = PU_Info_pu_dst( pu_info );
02132
02133
02134
02135 info = DST_INFO_IDX_TO_PTR( dst );
02136 iattr = DST_INFO_attributes( info );
02137 child_idx = DST_SUBPROGRAM_def_first_child(
02138 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBPROGRAM));
02139 while (!DST_IS_NULL(child_idx)) {
02140 info = DST_INFO_IDX_TO_PTR( child_idx );
02141 tag = DST_INFO_tag(info);
02142 flag = DST_INFO_flag(info);
02143 iattr = DST_INFO_attributes(info);
02144 level = ST_level(st);
02145 index = ST_index(st);
02146 switch (tag)
02147 {
02148 case DW_TAG_formal_parameter:
02149 assoc = &DST_FORMAL_PARAMETER_st(
02150 DST_ATTR_IDX_TO_PTR(iattr, DST_FORMAL_PARAMETER));
02151 break;
02152 case DW_TAG_variable:
02153 assoc = &DST_VARIABLE_def_st(
02154 DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE));
02155 break;
02156 default:
02157 goto next;
02158 }
02159 if (pDST_ASSOC_INFO_st_level(assoc) == level
02160 && pDST_ASSOC_INFO_st_index(assoc) == index) {
02161
02162
02163
02164 DST_INFO_IDX name_idx;
02165
02166 if (tag == DW_TAG_formal_parameter) {
02167 name_idx = DST_FORMAL_PARAMETER_name(DST_ATTR_IDX_TO_PTR(iattr,
02168 DST_FORMAL_PARAMETER));
02169 } else if (tag == DW_TAG_variable) {
02170 DST_VARIABLE *vattr = DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE);
02171
02172 name_idx = DST_IS_comm(flag) ? DST_VARIABLE_comm_name(vattr) :
02173 DST_VARIABLE_def_name(vattr);
02174 } else
02175 Fail_FmtAssertion("impossible tag == %d\n", (INT) tag);
02176
02177 if (DST_IS_NULL(name_idx))
02178 goto next;
02179
02180 return child_idx;
02181 }
02182 next:
02183 child_idx = DST_INFO_sibling(DST_INFO_IDX_TO_PTR(child_idx));
02184 }
02185 return( DST_INVALID_IDX );
02186 }
02187
02188
02189 extern void
02190 Create_New_DST ( DST_INFO_IDX dst, ST *st , BOOL append_to_nested )
02191 {
02192 DST_INFO *info;
02193 DST_INFO_IDX new_dst, type_idx;
02194 DST_ASSOC_INFO *assoc;
02195 DST_DW_tag tag;
02196 DST_flag flag;
02197 DST_ATTR_IDX iattr;
02198 DST_VARIABLE *vattr;
02199 DST_FORMAL_PARAMETER *fattr;
02200 USRCPOS srcpos;
02201 char *name;
02202
02203 USRCPOS_srcpos(srcpos) = 0LL;
02204 info = DST_INFO_IDX_TO_PTR( dst );
02205 tag = DST_INFO_tag(info);
02206 iattr = DST_INFO_attributes(info);
02207 flag = DST_INFO_flag(info);
02208 type_idx = DST_INVALID_IDX;
02209 switch (tag)
02210 {
02211 case DW_TAG_formal_parameter:
02212 fattr = DST_ATTR_IDX_TO_PTR(iattr, DST_FORMAL_PARAMETER);
02213 type_idx = DST_FORMAL_PARAMETER_type( fattr );
02214 name = DST_STR_IDX_TO_PTR( DST_FORMAL_PARAMETER_name( fattr ) );
02215 break;
02216 case DW_TAG_variable:
02217 if (DST_IS_comm(flag)) {
02218 vattr = DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE);
02219 type_idx = DST_VARIABLE_comm_type( vattr );
02220 name = DST_STR_IDX_TO_PTR( DST_VARIABLE_comm_name( vattr ) );
02221 }
02222 else {
02223 vattr = DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE);
02224 type_idx = DST_VARIABLE_def_type( vattr );
02225 name = DST_STR_IDX_TO_PTR( DST_VARIABLE_def_name( vattr ) );
02226 }
02227 break;
02228 default:
02229 Fail_FmtAssertion( "Unimplemented local MP variable kind" );
02230 }
02231 new_dst = DST_mk_variable( srcpos,
02232 name,
02233 type_idx,
02234 0 ,
02235 ST_st_idx(st),
02236 DST_INVALID_IDX,
02237 FALSE,
02238 TRUE,
02239 FALSE,
02240 FALSE);
02241
02242 if (append_to_nested)
02243 (void)DST_append_child( nested_dst, new_dst );
02244 info = DST_INFO_IDX_TO_PTR( new_dst );
02245 #if 0
02246 iattr = DST_INFO_attributes(info);
02247 assoc = &DST_VARIABLE_def_st(
02248 DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE));
02249 pDST_ASSOC_INFO_st_idx(assoc) = ST_st_idx(st);
02250 DST_SET_assoc_idx(DST_INFO_flag(info));
02251 DST_RESET_assoc_fe(DST_INFO_flag(info));
02252 #endif
02253 }
02254
02255
02256 static void
02257 Create_Func_DST ( char * st_name )
02258 {
02259 DST_INFO_IDX dst = PU_Info_pu_dst( Current_PU_Info );
02260 DST_INFO *info = DST_INFO_IDX_TO_PTR(dst);
02261 DST_ASSOC_INFO *assoc;
02262 USRCPOS srcpos;
02263
02264 USRCPOS_srcpos(srcpos) = line_number;
02265 nested_dst = DST_mk_subprogram( srcpos,
02266 st_name,
02267 DST_INVALID_IDX,
02268 DST_INVALID_IDX,
02269 ST_st_idx(parallel_proc),
02270 DW_INL_not_inlined,
02271 DW_VIRTUALITY_none,
02272 0,
02273 FALSE,
02274 FALSE,
02275 #ifdef KEY
02276 FALSE,
02277 #endif
02278 FALSE
02279 );
02280 (void)DST_append_child( dst, nested_dst );
02281 #if 0
02282 info = DST_INFO_IDX_TO_PTR( nested_dst );
02283 assoc = &DST_SUBPROGRAM_def_st(
02284 DST_ATTR_IDX_TO_PTR(DST_INFO_attributes(info), DST_SUBPROGRAM));
02285 pDST_ASSOC_INFO_st_idx(assoc) = ST_st_idx(parallel_proc);
02286 DST_SET_assoc_idx(DST_INFO_flag(info));
02287 DST_RESET_assoc_fe(DST_INFO_flag(info));
02288 #endif
02289 }
02290
02291
02292
02293
02294 static BOOL
02295 Identical_Pragmas ( WN * wn1, WN * wn2 )
02296 {
02297 INT32 i;
02298
02299 if ((WN_operator(wn1) != WN_operator(wn2)) ||
02300 (WN_pragma(wn1) != WN_pragma(wn2)) ||
02301 (WN_st(wn1) != WN_st(wn2)) ||
02302 (WN_pragma_flags(wn1) != WN_pragma_flags(wn2)) ||
02303 ((WN_operator(wn1) == OPR_PRAGMA) &&
02304 (WN_pragma_arg64(wn1) != WN_pragma_arg64(wn2))) ||
02305 (WN_kid_count(wn1) != WN_kid_count(wn2)))
02306 return (FALSE);
02307
02308 for (i = 0; i < WN_kid_count(wn1); i++)
02309 if (WN_Compare_Trees(WN_kid(wn1, i), WN_kid(wn2, i)) != 0)
02310 return (FALSE);
02311
02312 return (TRUE);
02313 }
02314
02315
02316
02317
02318
02319
02320 static void
02321 Create_Temp( TYPE_ID mtype, const char *name, ST **st )
02322 {
02323 ST *new_st;
02324 new_st = New_ST (CURRENT_SYMTAB);
02325 ST_Init (new_st,
02326 Save_Str2 ( "__ompv_temp_", name ),
02327 CLASS_VAR,
02328 SCLASS_AUTO,
02329 EXPORT_LOCAL,
02330 MTYPE_To_TY (mtype));
02331 Set_ST_is_temp_var ( new_st );
02332 *st = new_st;
02333 }
02334
02335 #ifdef KEY
02336
02337
02338 static ST_IDX Localize_Symbol (ST_IDX old_st_idx, VAR_TABLE * v)
02339 {
02340 for ( ; v->orig_st; v++) {
02341 if (ST_st_idx(*v->orig_st) == old_st_idx &&
02342 v->vtype == VAR_LOCAL) {
02343 return ST_st_idx(*v->new_st);
02344 }
02345 }
02346
02347 ST_IDX new_st_idx = 0;
02348
02349 ST * new_st = New_ST (CURRENT_SYMTAB);
02350 ST * old_st = &St_Table[old_st_idx];
02351 ST_Init (new_st,
02352 Save_Str (ST_name(old_st_idx)),
02353 ST_class(old_st),
02354 ST_sclass(old_st),
02355 ST_export(old_st),
02356 ST_type(old_st));
02357 new_st->flags = old_st->flags;
02358 new_st->flags_ext = old_st->flags_ext;
02359
02360 return ST_st_idx(new_st);
02361 }
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373 static INITO_IDX
02374 Process_PU_Exc_Info ( INITO_IDX old_inito, VAR_TABLE * vtab )
02375 {
02376 INITO_IDX new_inito;
02377 ST *old_initst, *new_initst;
02378 INITV_IDX old_initv, new_initv, pinito, parent, prev;
02379 STACK<INITV_IDX> old_stack(Malloc_Mem_Pool), new_stack(Malloc_Mem_Pool);
02380
02381 old_initst = INITO_st(old_inito);
02382 old_initv = INITO_val(old_inito);
02383
02384
02385 new_initst = New_ST (CURRENT_SYMTAB);
02386 ST_Init (new_initst,
02387 Save_Str ( ST_name(old_initst) ),
02388 ST_class(old_initst),
02389 ST_sclass(old_initst),
02390 ST_export(old_initst),
02391 ST_type(old_initst));
02392
02393 new_initst->flags = old_initst->flags;
02394 new_initst->flags_ext = old_initst->flags_ext;
02395
02396 Set_ST_is_not_used(*old_initst);
02397
02398 new_inito = New_INITO ( new_initst );
02399
02400 pinito = new_inito;
02401 parent = 0;
02402 prev = 0;
02403
02404
02405 for (INT i = 0; i < 2; i++)
02406 {
02407 (void) Initv_Table.New_entry(new_initv);
02408 INITV& new_initv_ref = Initv_Table[new_initv];
02409 INITV& old_initv_ref = Initv_Table[old_initv];
02410 if (pinito) {
02411 Set_INITO_val(pinito, new_initv);
02412 pinito = 0;
02413 } else if (prev) {
02414 Set_INITV_next(prev, new_initv);
02415 }
02416 INITVKIND k = INITV_kind(old_initv);
02417 Is_True (k == INITVKIND_VAL,
02418 ("Unexpected initv kind during PU exception processing"));
02419 INITO_IDX inito = 0;
02420 ST_IDX st = TCON_uval(INITV_tc_val(old_initv_ref));
02421 if (st)
02422 st = Localize_Symbol (st, vtab);
02423 INITV_Set_VAL(new_initv_ref, Enter_tcon (Host_To_Targ (MTYPE_U4, st)),
02424 INITV_repeat2(old_initv_ref));
02425 old_initv = INITV_next(old_initv);
02426 prev = new_initv;
02427 }
02428
02429 INITO_IDX old_inito_array[2] = {0, 0};
02430 INITO_IDX new_inito_array[2] = {0, 0};
02431
02432
02433 for (INT i = 0; i < 2; i++)
02434 {
02435 (void) Initv_Table.New_entry(new_initv);
02436 INITV& new_initv_ref = Initv_Table[new_initv];
02437 INITV& old_initv_ref = Initv_Table[old_initv];
02438 if (prev)
02439 Set_INITV_next(prev, new_initv);
02440 INITVKIND k = INITV_kind(old_initv);
02441 Is_True (k == INITVKIND_VAL,
02442 ("Unexpected initv kind during typeinfo/EH-spec processing"));
02443
02444 INITO_IDX inito = 0;
02445 ST_IDX st = TCON_uval(INITV_tc_val(old_initv_ref));
02446 if (st)
02447 {
02448 inito = (INITO_IDX) st;
02449 st = Localize_Symbol (INITO_st_idx(Inito_Table[inito]), vtab);
02450 INITO_IDX new_inito = New_INITO (st, INITO_val(inito));
02451
02452 INITV_Set_VAL(new_initv_ref, Enter_tcon (Host_To_Targ (MTYPE_U4,
02453 new_inito)),
02454 INITV_repeat2(old_initv_ref));
02455 old_inito_array[i] = inito;
02456 new_inito_array[i] = new_inito;
02457 }
02458 else
02459 INITV_Set_VAL(new_initv_ref, Enter_tcon (Host_To_Targ (MTYPE_U4, st)),
02460 INITV_repeat2(old_initv_ref));
02461 old_initv = INITV_next(old_initv);
02462 prev = new_initv;
02463 }
02464
02465 for (INT i = 0; i < 2; i++) {
02466
02467
02468
02469 old_initv = old_inito_array[i] ? INITO_val(old_inito_array[i]) : 0;
02470 pinito = new_inito_array[i];
02471 parent = prev = 0;
02472
02473 while ( old_initv ) {
02474
02475 (void) Initv_Table.New_entry(new_initv);
02476 INITV& new_initv_ref = Initv_Table[new_initv];
02477 INITV& old_initv_ref = Initv_Table[old_initv];
02478
02479 if (pinito) {
02480 Set_INITO_val(pinito, new_initv);
02481 pinito = 0;
02482 } else if (parent) {
02483 Set_INITV_blk(parent, new_initv);
02484 parent = 0;
02485 } else if (prev) {
02486 Set_INITV_next(prev, new_initv);
02487 }
02488
02489 INITVKIND k = INITV_kind(old_initv);
02490 switch ( k ) {
02491
02492 case INITVKIND_ZERO:
02493 INITV_Set_ZERO(new_initv_ref, INITV_mtype(old_initv_ref),
02494 INITV_repeat2(old_initv_ref));
02495 old_initv = INITV_next(old_initv);
02496 prev = new_initv;
02497 break;
02498
02499 case INITVKIND_ONE:
02500 INITV_Set_ONE(new_initv_ref, INITV_mtype(old_initv_ref),
02501 INITV_repeat2(old_initv_ref));
02502 old_initv = INITV_next(old_initv);
02503 prev = new_initv;
02504 break;
02505
02506 case INITVKIND_VAL:
02507 {
02508 ST_IDX st = TCON_uval(INITV_tc_val(old_initv_ref));
02509 INITV_Set_VAL(new_initv_ref, Enter_tcon (Host_To_Targ (MTYPE_U4, st)),
02510 INITV_repeat2(old_initv_ref));
02511 old_initv = INITV_next(old_initv);
02512 prev = new_initv;
02513 }
02514 break;
02515
02516 case INITVKIND_BLOCK:
02517 INITV_Set_BLOCK(new_initv_ref, INITV_repeat1(old_initv_ref), 0);
02518 old_stack.Push(old_initv);
02519 new_stack.Push(new_initv);
02520 old_initv = INITV_blk(old_initv);
02521 parent = new_initv;
02522 prev = 0;
02523 break;
02524
02525 default:
02526 Fail_FmtAssertion ( "unexpected INITV kind %d", (INT) k );
02527 }
02528
02529 while (!old_initv && old_stack.Elements() > 0) {
02530 old_initv = INITV_next(old_stack.Pop());
02531 prev = new_stack.Pop();
02532 }
02533 }
02534 }
02535
02536 return new_inito;
02537 }
02538 #endif
02539
02540 static WN * Gen_MP_Store ( ST * st, WN_OFFSET offset, WN * value,
02541 BOOL scalar_only = FALSE );
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551 static void
02552 Create_MicroTask ( PAR_FUNC_TYPE func_type )
02553 {
02554 BOOL is_do32 = FALSE, is_do64 = FALSE, is_region = FALSE;
02555 switch (func_type) {
02556 case PAR_FUNC_DO32:
02557 is_do32 = TRUE;
02558 break;
02559 case PAR_FUNC_DO64:
02560 is_do64 = TRUE;
02561 break;
02562 case PAR_FUNC_REGION:
02563 is_region = TRUE;
02564 break;
02565 default:
02566 Fail_FmtAssertion("invalid parallel function type %d", (INT) func_type);
02567 break;
02568 }
02569
02570
02571 const char *construct_type_str = is_region ? "ompregion" : "ompdo";
02572 char temp_str[64];
02573
02574
02575
02576
02577 TY_IDX &func_ty_idx = mpregion_ty;
02578
02579 if (func_ty_idx == TY_IDX_ZERO) {
02580
02581
02582 TY& ty = New_TY(func_ty_idx);
02583 sprintf(temp_str, ".%s", construct_type_str);
02584 TY_Init(ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str(temp_str));
02585 Set_TY_align(func_ty_idx, 1);
02586
02587 TYLIST_IDX parm_idx;
02588 TYLIST& parm_list = New_TYLIST(parm_idx);
02589 Set_TY_tylist(ty, parm_idx);
02590 Set_TYLIST_type(parm_list, Be_Type_Tbl(MTYPE_V));
02591
02592
02593 Set_TYLIST_type(New_TYLIST(parm_idx),
02594 Be_Type_Tbl(Pointer_type));
02595 Set_TYLIST_type(New_TYLIST(parm_idx),
02596 Be_Type_Tbl(Pointer_type));
02597
02598 Set_TYLIST_type(New_TYLIST(parm_idx), TY_IDX_ZERO);
02599
02600
02601 TY_IDX ptr_ty_idx;
02602 TY &ptr_ty = New_TY(ptr_ty_idx);
02603 sprintf(temp_str, ".%s_ptr", construct_type_str);
02604 TY_Init(ptr_ty, Pointer_Size, KIND_POINTER, Pointer_Mtype,
02605 Save_Str(temp_str));
02606 Set_TY_pointed(ptr_ty, func_ty_idx);
02607 }
02608
02609
02610
02611
02612 INT32 mp_region_num;
02613 INT32 mp_construct_num;
02614
02615 if (mpnum_node)
02616 mp_region_num = WN_pragma_arg1(mpnum_node);
02617 else
02618
02619 mp_region_num = ++(is_region ? region_id : do_id);
02620 mp_construct_num = mpid_table[mp_region_num]++;
02621
02622 const char *old_st_name = ST_name(PU_Info_proc_sym(Current_PU_Info));
02623 char *st_name = (char *) alloca(strlen(old_st_name) + 32);
02624 if (mp_construct_num == 0)
02625 sprintf ( st_name, "__%s_%s%d", construct_type_str, old_st_name,
02626 mp_region_num );
02627 else
02628 sprintf ( st_name, "__%s_%s%d.%d", construct_type_str, old_st_name,
02629 mp_region_num, mp_construct_num );
02630
02631
02632
02633
02634 PU_IDX pu_idx;
02635 PU& pu = New_PU(pu_idx);
02636 PU_Init(pu, func_ty_idx, CURRENT_SYMTAB);
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649 Set_PU_no_inline(pu);
02650 Set_PU_is_nested_func(pu);
02651 Set_PU_mp(pu);
02652 #ifdef KEY
02653 Set_PU_mp_lower_generated(pu);
02654 #endif // KEY
02655
02656 if (PU_c_lang(Current_PU_Info_pu()))
02657 Set_PU_c_lang(pu);
02658 if (PU_cxx_lang(Current_PU_Info_pu()))
02659 Set_PU_cxx_lang(pu);
02660 if (PU_f77_lang(Current_PU_Info_pu()))
02661 Set_PU_f77_lang(pu);
02662 if (PU_f90_lang(Current_PU_Info_pu()))
02663 Set_PU_f90_lang(pu);
02664 if (PU_java_lang(Current_PU_Info_pu()))
02665 Set_PU_java_lang(pu);
02666
02667 Set_FILE_INFO_has_mp(File_info);
02668
02669 parallel_proc = New_ST(GLOBAL_SYMTAB);
02670 ST_Init(parallel_proc,
02671 Save_Str (st_name),
02672 CLASS_FUNC,
02673 SCLASS_TEXT,
02674 EXPORT_LOCAL,
02675 pu_idx);
02676 Set_ST_addr_passed(parallel_proc);
02677
02678 Allocate_Object ( parallel_proc );
02679
02680
02681
02682
02683 New_Scope(CURRENT_SYMTAB + 1,
02684 Malloc_Mem_Pool,
02685 TRUE);
02686 csymtab = CURRENT_SYMTAB;
02687 func_level = CURRENT_SYMTAB;
02688 Scope_tab[csymtab].st = parallel_proc;
02689
02690 Set_PU_lexical_level(pu, CURRENT_SYMTAB);
02691
02692 Create_Func_DST ( st_name );
02693
02694
02695
02696
02697 for (UINT32 i = 1; i < PREG_Table_Size(psymtab); i++) {
02698 PREG_IDX preg_idx;
02699 PREG &preg = New_PREG(csymtab, preg_idx);
02700
02701 Set_PREG_name_idx(preg,
02702 PREG_name_idx((*Scope_tab[psymtab].preg_tab)[preg_idx]));
02703 }
02704
02705
02706
02707 ST *arg_gtid = New_ST( CURRENT_SYMTAB );
02708 ST_Init (arg_gtid,
02709 Save_Str ( "__ompv_gtid_a" ),
02710 CLASS_VAR,
02711 SCLASS_FORMAL,
02712 EXPORT_LOCAL,
02713 Be_Type_Tbl(MTYPE_I4));
02714 Set_ST_is_value_parm( arg_gtid );
02715
02716 ST *arg_slink = New_ST( CURRENT_SYMTAB );
02717 ST_Init( arg_slink,
02718 Save_Str( "__ompv_slink_a" ),
02719 CLASS_VAR,
02720 SCLASS_FORMAL,
02721 EXPORT_LOCAL,
02722 Be_Type_Tbl( Pointer_type ));
02723 Set_ST_is_value_parm( arg_slink );
02724
02725
02726
02727
02728
02729
02730 parallel_func = WN_CreateBlock ( );
02731 reference_block = WN_CreateBlock ( );
02732 #ifdef KEY
02733 WN *thread_priv_prag = WN_first(WN_func_pragmas(PU_Info_tree_ptr(Current_PU_Info)));
02734 if (thread_priv_prag) {
02735 while (thread_priv_prag) {
02736 if (WN_opcode(thread_priv_prag) == OPC_PRAGMA &&
02737 WN_pragma(thread_priv_prag) == WN_PRAGMA_THREADPRIVATE) {
02738 WN_INSERT_BlockLast ( reference_block,
02739 WN_CreatePragma ( WN_PRAGMA_THREADPRIVATE,
02740 WN_st_idx(thread_priv_prag),
02741 WN_pragma_arg1(thread_priv_prag),
02742 WN_pragma_arg2(thread_priv_prag) ));
02743 }
02744 thread_priv_prag = WN_next(thread_priv_prag);
02745 }
02746 }
02747 #endif
02748
02749 WN *func_entry = WN_CreateEntry ( 2, parallel_proc,
02750 parallel_func, WN_CreateBlock ( ),
02751 reference_block );
02752
02753 WN_kid0(func_entry) = WN_CreateIdname ( 0, arg_gtid );
02754 WN_kid1(func_entry) = WN_CreateIdname ( 0, arg_slink );
02755
02756
02757 WN_linenum(func_entry) = line_number;
02758
02759
02760
02761 ST *slink = Gen_Temp_Symbol (MTYPE_To_TY(Pointer_type), "__slink_sym");
02762
02763 Is_True( slink != NULL, ("The slink should not be NULL"));
02764 WN *wn_store_slink = Gen_MP_Store( slink, 0,
02765 WN_Ldid( Pointer_type, 0, arg_slink, ST_type( arg_slink ), 0 ));
02766 WN_linenum( wn_store_slink ) = line_number;
02767 WN_INSERT_BlockLast( parallel_func, wn_store_slink );
02768
02769
02770
02771
02772
02773
02774 Create_Temp( MTYPE_I4, "gtid", &local_gtid );
02775 WN *wn_store_gtid = Gen_MP_Store( local_gtid, 0,
02776 WN_Ldid( MTYPE_I4, 0, arg_gtid, ST_type(arg_gtid), 0 ));
02777
02778 WN_linenum( wn_store_gtid ) = line_number;
02779 WN_INSERT_BlockLast( parallel_func, wn_store_gtid );
02780
02781
02782
02783 PU_Info *parallel_pu = TYPE_MEM_POOL_ALLOC ( PU_Info, Malloc_Mem_Pool );
02784 PU_Info_init ( parallel_pu );
02785 Set_PU_Info_tree_ptr (parallel_pu, func_entry );
02786 verify_mp_lowered_ptr->Set_nested_pu_tree(func_entry);
02787
02788 PU_Info_proc_sym(parallel_pu) = ST_st_idx(parallel_proc);
02789 PU_Info_maptab(parallel_pu) = cmaptab = WN_MAP_TAB_Create(MEM_pu_pool_ptr);
02790 PU_Info_pu_dst(parallel_pu) = nested_dst;
02791 Set_PU_Info_state(parallel_pu, WT_SYMTAB, Subsect_InMem);
02792 Set_PU_Info_state(parallel_pu, WT_TREE, Subsect_InMem);
02793 Set_PU_Info_state(parallel_pu, WT_PROC_SYM, Subsect_InMem);
02794 Set_PU_Info_flags(parallel_pu, PU_IS_COMPILER_GENERATED);
02795
02796
02797
02798
02799
02800
02801
02802 Set_PU_Info_symtab_ptr(parallel_pu, NULL);
02803 Save_Local_Symtab(csymtab, parallel_pu);
02804
02805 Is_True(PU_Info_state(parallel_pu, WT_FEEDBACK) == Subsect_Missing,
02806 ("there should be no feedback for parallel_pu"));
02807 if (Cur_PU_Feedback) {
02808 #ifdef KEY
02809 parallel_pu_fb = CXX_NEW(FEEDBACK(func_entry,
02810 MEM_pu_nz_pool_ptr,
02811 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
02812 cmaptab),
02813 MEM_pu_nz_pool_ptr);
02814 #else
02815 parallel_pu_fb = CXX_NEW(FEEDBACK(func_entry,
02816 MEM_pu_nz_pool_ptr,
02817 1, 1, 1, 1, 1, 1,
02818 cmaptab),
02819 MEM_pu_nz_pool_ptr);
02820 #endif
02821 Set_PU_Info_state(parallel_pu, WT_FEEDBACK, Subsect_InMem);
02822 Set_PU_Info_feedback_ptr(parallel_pu, parallel_pu_fb);
02823
02824
02825
02826
02827 FB_Transfer(Cur_PU_Feedback, parallel_pu_fb, stmt_block);
02828 }
02829
02830 RID *root_rid = RID_Create ( 0, 0, func_entry );
02831 RID_type(root_rid) = RID_TYPE_func_entry;
02832 Set_PU_Info_regions_ptr ( parallel_pu, root_rid );
02833 Is_True(PU_Info_regions_ptr(parallel_pu) != NULL,
02834 ("Create_MicroTask, NULL root RID"));
02835
02836 PU_Info *tpu = PU_Info_child(Current_PU_Info);
02837
02838
02839 if (tpu && PU_Info_state(tpu, WT_SYMTAB) == Subsect_InMem &&
02840 PU_mp(PU_Info_pu(tpu)) ) {
02841 PU_Info *npu;
02842
02843 while ((npu = PU_Info_next(tpu)) &&
02844 PU_Info_state(npu, WT_SYMTAB) == Subsect_InMem &&
02845 PU_mp(PU_Info_pu(npu)) )
02846 tpu = npu;
02847
02848 PU_Info_next(tpu) = parallel_pu;
02849 PU_Info_next(parallel_pu) = npu;
02850 } else {
02851 PU_Info_child(Current_PU_Info) = parallel_pu;
02852 PU_Info_next(parallel_pu) = tpu;
02853 }
02854
02855
02856
02857
02858 Current_PU_Info = parallel_pu;
02859 Current_pu = &Current_PU_Info_pu();
02860 Current_Map_Tab = pmaptab;
02861
02862 Add_DST_variable ( arg_gtid, nested_dst, line_number, DST_INVALID_IDX );
02863 Add_DST_variable ( arg_slink, nested_dst, line_number, DST_INVALID_IDX );
02864
02865 }
02866
02867
02868
02869
02870 static void
02871 Create_Preg_or_Temp ( TYPE_ID mtype, const char *name, ST **st,
02872 WN_OFFSET *ofst )
02873 {
02874 ST *new_st;
02875
02876 if (!pu_has_eh) {
02877 *st = MTYPE_To_PREG ( mtype );
02878 *ofst = Create_Preg (mtype, name);
02879 } else {
02880 new_st = New_ST (CURRENT_SYMTAB);
02881 ST_Init (new_st,
02882 Save_Str2 ( "__ompv_temp_", name ),
02883 CLASS_VAR,
02884 SCLASS_AUTO,
02885 EXPORT_LOCAL,
02886 MTYPE_To_TY (mtype));
02887 Set_ST_is_temp_var ( new_st );
02888 *st = new_st;
02889 *ofst = 0;
02890 }
02891 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903 static BOOL
02904 Is_Master_Test(WN *tree)
02905 {
02906 if (WN_operator(tree) != OPR_EQ)
02907 return FALSE;
02908
02909 WN *wn_ldid;
02910
02911 if (WN_operator(WN_kid(tree, 0)) == OPR_LDID)
02912 wn_ldid = WN_kid(tree, 0);
02913 else if (WN_operator(WN_kid(tree, 1)) == OPR_LDID)
02914 wn_ldid = WN_kid(tree, 1);
02915 else
02916 return FALSE;
02917
02918 WN *wn_intconst = (wn_ldid == WN_kid(tree, 0)) ? WN_kid(tree, 1) :
02919 WN_kid(tree, 0);
02920
02921 if (WN_operator(wn_intconst) != OPR_INTCONST)
02922 return FALSE;
02923
02924 if (WN_const_val(wn_intconst) != 1 ||
02925 #ifdef KEY
02926 WN_class(wn_ldid) != CLASS_PREG ||
02927 #endif
02928 Preg_Is_Dedicated(WN_offset(wn_ldid)) ||
02929 strcmp(IS_MASTER_PREG_NAME, Preg_Name(WN_offset(wn_ldid))) != 0)
02930 return FALSE;
02931
02932 return TRUE;
02933 }
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946 static BOOL
02947 Is_Single_Test(WN *tree)
02948 {
02949 if (WN_operator(tree) != OPR_LDID ||
02950 #ifdef KEY
02951 WN_class(tree) != CLASS_PREG ||
02952 #endif
02953 Preg_Is_Dedicated(WN_offset(tree)) ||
02954 strcmp(MPSP_STATUS_PREG_NAME, Preg_Name(WN_offset(tree))) != 0)
02955
02956 return FALSE;
02957
02958 return TRUE;
02959 }
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970 static void
02971 Enter_Guarded_WNs(WN_TO_BOOL_HASH *guarded_set, WN *tree,
02972 BOOL tree_is_guarded = FALSE)
02973 {
02974 if (tree_is_guarded) {
02975
02976 guarded_set->Enter(tree, TRUE);
02977
02978 if (!OPCODE_is_leaf(WN_opcode(tree))) {
02979 if (WN_opcode(tree) == OPC_BLOCK) {
02980 for (WN *kid = WN_first(tree); kid; kid = WN_next(kid))
02981 Enter_Guarded_WNs(guarded_set, kid, TRUE);
02982 } else {
02983 for (INT kidno = 0; kidno < WN_kid_count(tree); kidno++) {
02984 WN *kid = WN_kid(tree, kidno);
02985 if (kid)
02986 Enter_Guarded_WNs(guarded_set, kid, TRUE);
02987 }
02988 }
02989 }
02990
02991 return;
02992 }
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014 if (WN_operator(tree) == OPR_INTRINSIC_CALL) {
03015 WN *lda = Get_ATOMIC_Update_LDA(tree);
03016 if (lda) {
03017 guarded_set->Enter(lda, TRUE);
03018 return;
03019 }
03020 }
03021
03022 OPCODE opc = WN_opcode(tree);
03023 ST_IDX end_st, end_name_st = ST_IDX_ZERO;
03024
03025 switch (opc) {
03026 case OPC_IF:
03027 if (Is_Master_Test(WN_if_test(tree)) ||
03028 Is_Single_Test(WN_if_test(tree)) )
03029 Enter_Guarded_WNs(guarded_set, WN_then(tree), TRUE);
03030 return;
03031 case OPC_VCALL:
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047 if (WN_st_idx(tree) == GET_MPRUNTIME_ST(MPR_OMP_CRITICAL)) {
03048
03049 end_st = GET_MPRUNTIME_ST(MPR_OMP_END_CRITICAL);
03050
03051 end_name_st = WN_st_idx(WN_kid0(WN_kid0(tree)));
03052 } else
03053 return;
03054 break;
03055 default:
03056 return;
03057 }
03058
03059 Is_True(opc == OPC_VCALL,
03060 ("should be looking for call that marks end of guarded code"));
03061
03062
03063
03064 DYN_ARRAY<WN *> nodes_in_critsect(Malloc_Mem_Pool);
03065
03066 for (WN *guarded_wn = WN_next(tree); guarded_wn;
03067 guarded_wn = WN_next(guarded_wn)) {
03068 if (WN_opcode(guarded_wn) == OPC_VCALL &&
03069 WN_st_idx(guarded_wn) == end_st &&
03070 (!end_name_st || WN_st_idx(WN_kid0(WN_kid0(guarded_wn))) ==
03071 end_name_st) )
03072 break;
03073 nodes_in_critsect.AddElement(guarded_wn);
03074 }
03075
03076
03077
03078 for (INT i = 0; i <= nodes_in_critsect.Lastidx(); i++)
03079 Enter_Guarded_WNs(guarded_set, nodes_in_critsect[i], TRUE);
03080 }
03081
03082
03083
03084
03085
03086
03087 static void
03088 Gather_Uplevel_References ( WN * block, INT32 level, WN * parent,
03089 WN * grandparent, WN * tree,
03090 WN_TO_BOOL_HASH *guarded_set )
03091 {
03092 WN *wn;
03093 WN *node;
03094 INT32 i;
03095 ST *st;
03096 OPCODE op;
03097 OPERATOR opr;
03098
03099 BOOL a_pointer;
03100 WN_PRAGMA_ACCESSED_FLAGS flags;
03101
03102 Is_True(level >= 2, ("impossible symtab level == %d", level));
03103
03104 if (tree) {
03105
03106 Enter_Guarded_WNs(guarded_set, tree);
03107
03108 op = WN_opcode(tree);
03109 opr = WN_operator(tree);
03110
03111 if (op == OPC_LOOP_INFO)
03112 return;
03113
03114 if (op == OPC_BLOCK)
03115 for (node = WN_first(tree); node; node = WN_next(node))
03116 Gather_Uplevel_References ( block, level, tree, parent, node,
03117 guarded_set );
03118 else
03119 for (i = 0; i < WN_kid_count(tree); i++)
03120 Gather_Uplevel_References ( block, level, tree, parent,
03121 WN_kid(tree, i), guarded_set );
03122
03123 if (OPCODE_has_sym(op) && (st = WN_st(tree)) != NULL &&
03124 ST_level(st) < level && ST_class(st) == CLASS_VAR) {
03125
03126 a_pointer = (TY_kind(ST_type(st)) == KIND_POINTER);
03127
03128 if (opr == OPR_LDID && !a_pointer)
03129 flags = ACCESSED_LOAD;
03130 else if (opr == OPR_STID)
03131 flags = ACCESSED_STORE;
03132 else if ((opr == OPR_LDA) && !a_pointer)
03133 if (WN_operator(parent) == OPR_ILOAD)
03134 flags = ACCESSED_LOAD;
03135 else if (WN_operator(parent) == OPR_ISTORE)
03136 flags = ACCESSED_STORE;
03137 else if (WN_operator(parent) == OPR_ARRAY)
03138 if (WN_operator(grandparent) == OPR_ILOAD)
03139 flags = ACCESSED_LOAD;
03140 else if (WN_operator(grandparent) == OPR_ISTORE)
03141 flags = ACCESSED_STORE;
03142 else
03143 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03144 ACCESSED_STORE |
03145 ACCESSED_ILOAD |
03146 ACCESSED_ISTORE);
03147 else
03148 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03149 ACCESSED_STORE |
03150 ACCESSED_ILOAD |
03151 ACCESSED_ISTORE);
03152 else if ((opr == OPR_LDID) && a_pointer)
03153 if (WN_operator(parent) == OPR_ILOAD)
03154 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03155 ACCESSED_ILOAD);
03156 else if (WN_operator(parent) == OPR_ISTORE)
03157 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03158 ACCESSED_ISTORE);
03159 else if (WN_operator(parent) == OPR_ARRAY)
03160 if (WN_operator(grandparent) == OPR_ILOAD)
03161 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03162 ACCESSED_ILOAD);
03163 else if (WN_operator(grandparent) == OPR_ISTORE)
03164 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03165 ACCESSED_ISTORE);
03166 else
03167 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03168 ACCESSED_STORE |
03169 ACCESSED_ILOAD |
03170 ACCESSED_ISTORE);
03171 else
03172 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03173 ACCESSED_STORE |
03174 ACCESSED_ILOAD |
03175 ACCESSED_ISTORE);
03176 else
03177 flags = (WN_PRAGMA_ACCESSED_FLAGS) (ACCESSED_LOAD |
03178 ACCESSED_STORE |
03179 ACCESSED_ILOAD |
03180 ACCESSED_ISTORE);
03181
03182 wn = WN_first(block);
03183 while (wn && (WN_st(wn) < st))
03184 wn = WN_next(wn);
03185 if (wn && (WN_st(wn) == st))
03186 WN_pragma_arg2(wn) |= flags;
03187 else {
03188 const ST_SCLASS sclass = ST_sclass(st);
03189
03190 if (sclass == SCLASS_AUTO || sclass == SCLASS_FORMAL_REF ||
03191 sclass == SCLASS_FORMAL || sclass == SCLASS_PSTATIC)
03192 Set_ST_has_nested_ref ( st );
03193
03194 WN_INSERT_BlockBefore ( block, wn,
03195 WN_CreatePragma ( WN_PRAGMA_ACCESSED_ID, st, 0,
03196 flags ));
03197 }
03198
03199 if ((flags & ACCESSED_STORE) && (TY_kind(ST_type(st)) == KIND_SCALAR)) {
03200 for (i = 0; (i < shared_count) && (st != shared_table[i]); i++) { }
03201 if (i == shared_count) {
03202 ST *split_blk, *common_blk = ST_Source_COMMON_Block(st, &split_blk);
03203 BOOL is_threadprivate_common =
03204 (ST_is_thread_private(st)) ||
03205 (split_blk && ST_is_thread_private(split_blk)) ||
03206 (common_blk && ST_is_thread_private(common_blk));
03207
03208 if (!Is_NameLock_ST(st) &&
03209 !is_threadprivate_common &&
03210 !guarded_set->Find(tree) &&
03211 #ifdef KEY
03212 strncmp(ST_name(st), "__thdprv", 8) &&
03213 #endif
03214 !comp_gen_construct) {
03215 #ifdef KEY
03216 USRCPOS srcpos;
03217 USRCPOS_srcpos(srcpos) = WN_Get_Linenum(tree);
03218 Set_Error_Line(USRCPOS_linenum(srcpos));
03219 #endif
03220 ErrMsg ( EC_MPLOWER_shared_store, st );
03221 }
03222 shared_table[shared_count++] = st;
03223 }
03224 }
03225
03226 }
03227
03228 if (((op == OPC_U4INTRINSIC_CALL) &&
03229 (WN_intrinsic(tree) == INTRN_U4I4ALLOCA)) ||
03230 ((op == OPC_U8INTRINSIC_CALL) &&
03231 (WN_intrinsic(tree) == INTRN_U8I8ALLOCA))) {
03232 Is_True(!Alloca_Dealloca_On,
03233 ("Alloca_Dealloca_On yet found INTRN_ALLOCA"));
03234 pu_has_alloca = TRUE;
03235 }
03236
03237 if (opr == OPR_ALLOCA) {
03238 Is_True(Alloca_Dealloca_On,
03239 ("found OPR_ALLOCA yet not Alloca_Dealloca_On"));
03240 pu_has_alloca = TRUE;
03241 }
03242
03243 if (op == OPC_REGION)
03244 pu_has_region = TRUE;
03245
03246 }
03247 }
03248
03249
03250
03251
03252 static void
03253 Walk_and_Info_Pregs ( WN * tree )
03254 {
03255 WN *node;
03256 INT32 i;
03257 OPCODE op;
03258
03259 if (tree) {
03260
03261 op = WN_opcode(tree);
03262 if (op == OPC_BLOCK)
03263 for (node = WN_first(tree); node; node = WN_next(node))
03264 Walk_and_Info_Pregs ( node );
03265 else
03266 for (i = 0; i < WN_kid_count(tree); i++)
03267 Walk_and_Info_Pregs ( WN_kid(tree, i) );
03268
03269 if (OPCODE_has_sym(op) && OPCODE_has_offset(op) && WN_st(tree) &&
03270 #ifdef KEY // bug 11914: if OPC_PRAGMA, WN_offsetx will not return correct pnum
03271 op != OPC_PRAGMA &&
03272 #endif
03273 (ST_class(WN_st(tree)) == CLASS_PREG) &&
03274 !Preg_Is_Dedicated(WN_offsetx(tree))) {
03275 PREG_IDX pnum = Get_Preg_Idx(WN_offsetx(tree));
03276
03277 PREG_INFO *preg = &preg_info_table->at(pnum);
03278
03279 if (preg->type == MTYPE_UNKNOWN)
03280 preg->type = ST_btype(WN_st(tree));
03281 }
03282 }
03283 }
03284
03285
03286
03287
03288 static void
03289 Walk_and_Replace_Pregs ( WN * tree )
03290 {
03291 WN *node;
03292 INT32 i;
03293 OPCODE op;
03294 PREG_INFO *preg;
03295
03296 if (tree) {
03297
03298 op = WN_opcode(tree);
03299 if (op == OPC_BLOCK)
03300 for (node = WN_first(tree); node; node = WN_next(node))
03301 Walk_and_Replace_Pregs ( node );
03302 else
03303 for (i = 0; i < WN_kid_count(tree); i++)
03304 Walk_and_Replace_Pregs ( WN_kid(tree, i) );
03305
03306 if (OPCODE_has_sym(op) && OPCODE_has_offset(op) && WN_st(tree) &&
03307 (ST_class(WN_st(tree)) == CLASS_PREG) &&
03308 !Preg_Is_Dedicated(WN_offsetx(tree)) ) {
03309 preg = &preg_info_table->at(Get_Preg_Idx(WN_offsetx(tree)));
03310
03311 if (preg->temp && (preg->pclass != PCLASS_COPYIN_DEADOUT)) {
03312 WN_st_idx(tree) = ST_st_idx(preg->temp);
03313 WN_set_offsetx(tree, 0);
03314 }
03315
03316 }
03317 }
03318 }
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331 static LABEL_IDX
03332 Translate_Label ( LABEL_IDX plabel_idx )
03333 {
03334 if (plabel_idx == LABEL_IDX_ZERO)
03335 return LABEL_IDX_ZERO;
03336
03337 if (mpt == MPP_ORPHANED_SINGLE || mpt == MPP_ORPHANED_PDO)
03338 return plabel_idx;
03339
03340 LABEL_IDX clabel_idx = label_info_table[LABEL_IDX_index(plabel_idx)];
03341
03342 if (clabel_idx == LABEL_IDX_ZERO) {
03343
03344 Is_True(csymtab != SYMTAB_IDX_ZERO, ("child symtab not created yet"));
03345 Is_True(psymtab != SYMTAB_IDX_ZERO, ("psymtab not set yet"));
03346 Is_True(psymtab < csymtab,
03347 ("fishy-looking psymtab %d and/or csymtab %d",
03348 (INT) psymtab, (INT) csymtab));
03349 Is_True(CURRENT_SYMTAB == csymtab, ("CURRENT_SYMTAB != csymtab"));
03350 char* Cur_PU_Name = ST_name(PU_Info_proc_sym(Current_PU_Info));
03351 INT strsize = strlen(User_Label_Number_Format) + 64 + strlen(Cur_PU_Name);
03352 char* labelname = (char*) calloc(strsize, 1);
03353 sprintf ( labelname, User_Label_Number_Format, (INT) csymtab,
03354 (INT) plabel_idx, ST_name(Get_Current_PU_ST()) );
03355
03356 LABEL &clabel = New_LABEL(csymtab, clabel_idx);
03357 LABEL_Init(clabel, Save_Str(labelname),
03358 LABEL_kind((*Scope_tab[psymtab].label_tab)[LABEL_IDX_index(plabel_idx)]));
03359 label_info_table[LABEL_IDX_index(plabel_idx)] = clabel_idx;
03360 }
03361
03362 return clabel_idx;
03363 }
03364
03365
03366
03367
03368 static BOOL
03369 Is_Kind_Array(const ST* st)
03370 {
03371 TY_IDX ty_idx = ST_type(st);
03372 if (TY_kind(ty_idx) == KIND_POINTER)
03373 ty_idx = TY_pointed(ty_idx);
03374 return TY_kind(ty_idx) == KIND_ARRAY;
03375 }
03376
03377
03378
03379
03380
03381
03382 static BOOL
03383 TY_All_Bounds_Defined(TY_IDX arr_ty)
03384 {
03385 Is_True(TY_kind(arr_ty) == KIND_ARRAY, ("not an array type"));
03386
03387 INT i;
03388 for (i = 0; i < TY_AR_ndims(arr_ty); i++) {
03389 if (!TY_AR_const_lbnd(arr_ty, i) &&
03390 TY_AR_lbnd_var(arr_ty, i) == 0)
03391 return FALSE;
03392 if (!TY_AR_const_ubnd(arr_ty, i) &&
03393 TY_AR_ubnd_var(arr_ty, i) == 0)
03394 return FALSE;
03395 }
03396
03397 return TRUE;
03398 }
03399
03400
03401
03402
03403 static WN *
03404 Calculate_Array_Size ( ST * st, TY_IDX ty )
03405 {
03406 INT32 i;
03407 WN *wn;
03408 WN *lower = NULL;
03409 WN *upper = NULL;
03410 const OPCODE int_opc = (Pointer_Size == 4) ? OPC_I4INTCONST :
03411 (Pointer_Size == 8) ? OPC_I8INTCONST : OPCODE_UNKNOWN;
03412 const mTYPE_ID int_mtype = (int_opc == OPC_I4INTCONST) ? MTYPE_I4 : MTYPE_I8;
03413
03414 Is_True(int_opc != OPCODE_UNKNOWN, ("invalid Pointer_Size"));
03415
03416 wn = WN_CreateIntconst ( int_opc, TY_size(TY_AR_etype(ty)) );
03417 for (i = 0; i < TY_AR_ndims(ty); i++) {
03418 if (TY_AR_const_lbnd(ty, i))
03419 lower = WN_CreateIntconst ( int_opc, TY_AR_lbnd_val(ty, i) );
03420 else {
03421 if (TY_AR_lbnd_var(ty,i)) {
03422 lower = WN_CreateLdid (OPCODE_make_op(OPR_LDID,
03423 TY_mtype(ST_type(TY_AR_lbnd_var(ty,i))),
03424 TY_mtype(ST_type(TY_AR_lbnd_var(ty,i)))),
03425 0, TY_AR_lbnd_var(ty,i),
03426 ST_type(TY_AR_lbnd_var(ty,i)));
03427 }
03428 else lower = NULL;
03429 }
03430 if (TY_AR_const_ubnd(ty, i))
03431 upper = WN_CreateIntconst ( int_opc, TY_AR_ubnd_val(ty, i) );
03432 else {
03433 if (TY_AR_ubnd_var(ty,i)) {
03434 upper = WN_CreateLdid (OPCODE_make_op(OPR_LDID,
03435 TY_mtype(ST_type(TY_AR_ubnd_var(ty,i))),
03436 TY_mtype(ST_type(TY_AR_ubnd_var(ty,i)))),
03437 0, TY_AR_ubnd_var(ty,i),
03438 ST_type(TY_AR_ubnd_var(ty,i)));
03439 }
03440 else upper = NULL;
03441 }
03442 if (upper && lower) {
03443 wn = WN_Mpy ( int_mtype, wn, WN_Add ( int_mtype,
03444 WN_Sub ( int_mtype, upper, lower ),
03445 WN_CreateIntconst ( int_opc,
03446 1 )));
03447 } else {
03448 ErrMsg ( EC_MPLOWER_local_nosize, st );
03449 WN_DELETE_Tree (wn);
03450 wn = WN_CreateIntconst ( int_opc, 0 );
03451 break;
03452 }
03453 }
03454
03455 return (wn);
03456 }
03457
03458
03459 static WN *
03460 Gen_Auto_Alloca(ST *st, WN_OFFSET offset, TY_IDX ty, WN *size)
03461 {
03462 WN *block = WN_CreateBlock(), *vla_stid_kid;
03463
03464 if (Alloca_Dealloca_On) {
03465
03466 vla_stid_kid = WN_CreateAlloca(size);
03467
03468 } else {
03469
03470 WN *intrin_call = WN_Create(
03471 (Pointer_Size == 4) ? OPC_U4INTRINSIC_CALL : OPC_U8INTRINSIC_CALL, 1);
03472 WN_intrinsic(intrin_call) = (Pointer_Size == 4) ? INTRN_U4I4ALLOCA :
03473 INTRN_U8I8ALLOCA;
03474 WN_Set_Call_Non_Data_Mod(intrin_call);
03475 WN_Set_Call_Non_Data_Ref(intrin_call);
03476 WN_Set_Call_Non_Parm_Mod(intrin_call);
03477 WN_Set_Call_Non_Parm_Ref(intrin_call);
03478 WN_Set_Call_Parm_Ref(intrin_call);
03479 WN_linenum(intrin_call) = line_number;
03480 WN_kid(intrin_call, 0) = WN_CreateParm(
03481 (Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8, size,
03482 Be_Type_Tbl((Pointer_Size == 4) ? MTYPE_I4 : MTYPE_I8),
03483 WN_PARM_BY_VALUE);
03484
03485 WN_INSERT_BlockLast(block, intrin_call);
03486
03487
03488 PREG_NUM rreg1, rreg2;
03489
03490 GET_RETURN_PREGS(rreg1, rreg2, Pointer_type);
03491 vla_stid_kid = WN_LdidPreg(Pointer_type, rreg1);
03492 }
03493
03494 WN *vla_stid = WN_Stid(Pointer_type, offset, st, ty, vla_stid_kid);
03495 WN_linenum(vla_stid) = line_number;
03496 WN_INSERT_BlockLast(block, vla_stid);
03497
03498 return block;
03499 }
03500
03501
03502
03503
03504
03505
03506 static vector<ST*> inner_scope_vla;
03507
03508 static void
03509 Gather_Inner_Scope_Vlas(WN *wn)
03510 {
03511 if (WN_operator(wn) == OPR_STID && WN_operator(WN_kid0(wn)) == OPR_ALLOCA) {
03512 inner_scope_vla.push_back(WN_st(wn));
03513 }
03514 else if (WN_operator(wn) == OPR_BLOCK) {
03515 for (WN *kid = WN_first(wn); kid; kid = WN_next(kid)) {
03516 Gather_Inner_Scope_Vlas(kid);
03517 }
03518 }
03519 else {
03520 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
03521 Gather_Inner_Scope_Vlas(WN_kid(wn, kidno));
03522 }
03523 }
03524 }
03525
03526 static BOOL
03527 Vla_Needs_Alloca(ST *st)
03528 {
03529 vector<ST*>::iterator i;
03530 for (i = inner_scope_vla.begin(); i != inner_scope_vla.end(); i++) {
03531 if (*i == st) {
03532 return FALSE;
03533 }
03534 }
03535 return TRUE;
03536 }
03537
03538 #ifdef KEY
03539
03540 class Localized_thdprv_var
03541 {
03542 ST_IDX var;
03543 ST_IDX localized;
03544
03545 public:
03546 Localized_thdprv_var (ST_IDX v, ST_IDX l) : var (v), localized (l) {}
03547 ST_IDX Thdprv_ptr (void) const { return var; }
03548 ST_IDX Thdprv_local (void) const { return localized; }
03549 };
03550
03551
03552 std::vector<Localized_thdprv_var> localized_var_vect;
03553 #endif // KEY
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565 static void
03566 Localize_Variable ( VAR_TABLE *v, VAR_TYPE vtype, OPERATOR opr,
03567 WN *vtree, ST *old_st, WN_OFFSET old_offset,
03568 WN **firstprivate_blockp, WN **alloca_blockp,
03569 VAR_TABLE *prev_def )
03570 {
03571 ST *sym;
03572 TY_IDX ty;
03573 char *localname;
03574 DST_INFO_IDX dst;
03575 const BOOL orphaned =
03576 (mpt == MPP_ORPHANED_SINGLE || mpt == MPP_ORPHANED_PDO);
03577
03578 Is_True(!prev_def || vtype == VAR_FIRSTPRIVATE,
03579 ("prev_def only valid for VAR_FIRSTPRIVATE"));
03580 Is_True(!prev_def || prev_def->vtype == VAR_LASTLOCAL ||
03581 prev_def->vtype == VAR_LOCAL,
03582 ("invalid vtype for prev_def"));
03583
03584
03585 switch (vtype) {
03586 case VAR_LASTLOCAL:
03587 case VAR_LOCAL:
03588 case VAR_FIRSTPRIVATE:
03589 if (Has_Base_Block(old_st) && ST_is_equivalenced(old_st)) {
03590
03591
03592
03593
03594 if (comp_gen_construct) {
03595
03596 break;
03597 }
03598
03599 #ifndef KEY
03600 ErrMsg(EC_MPLOWER_priv_equiv, old_st);
03601 #endif
03602 return;
03603 }
03604 break;
03605 default:
03606 break;
03607 }
03608
03609 v->vtype = vtype;
03610 v->is_static_array = ((ST_sclass(old_st) == SCLASS_FORMAL) &&
03611 ((vtype == VAR_LOCAL) || (vtype == VAR_LASTLOCAL) ||
03612 (vtype == VAR_FIRSTPRIVATE)) &&
03613 (TY_kind(ST_type(old_st)) == KIND_POINTER) &&
03614 (TY_kind(TY_pointed(ST_type(old_st))) == KIND_ARRAY) &&
03615 (TY_size(TY_pointed(ST_type(old_st))) != 0));
03616 v->is_dynamic_array = (((vtype == VAR_LOCAL) || (vtype == VAR_LASTLOCAL) ||
03617 (vtype == VAR_FIRSTPRIVATE)) &&
03618 (TY_kind(ST_type(old_st)) == KIND_POINTER) &&
03619 (ST_keep_name_w2f(old_st) ||
03620 PU_src_lang(Get_Current_PU()) == PU_F77_LANG ||
03621 PU_src_lang(Get_Current_PU()) == PU_F90_LANG) &&
03622 (TY_kind(TY_pointed(ST_type(old_st))) == KIND_ARRAY) &&
03623 (TY_size(TY_pointed(ST_type(old_st))) == 0) &&
03624 TY_All_Bounds_Defined(TY_pointed(
03625 ST_type(old_st)) ) );
03626 v->is_non_pod = ( ST_class(old_st) != CLASS_PREG &&
03627 ( TY_kind(ST_type(old_st)) == KIND_STRUCT &&
03628 TY_is_non_pod(ST_type(old_st)) ) ||
03629 ( TY_kind(ST_type(old_st)) == KIND_ARRAY &&
03630 TY_kind(TY_etype(ST_type(old_st))) == KIND_STRUCT &&
03631 TY_is_non_pod(TY_etype(ST_type(old_st)))));
03632 v->vtree = vtree;
03633 v->vtreex = NULL;
03634 v->orig_st = old_st;
03635 v->orig_offset = old_offset;
03636
03637 #ifdef Is_True_On
03638 if (v->is_non_pod)
03639 switch (mpt) {
03640 case MPP_SINGLE:
03641 case MPP_ORPHANED_SINGLE:
03642 case MPP_PDO:
03643 case MPP_ORPHANED_PDO:
03644 case MPP_PARALLEL_REGION:
03645 break;
03646 default:
03647 Fail_FmtAssertion("non-POD object invalidly privatized on construct "
03648 "with mpt == %d", (INT) mpt);
03649 }
03650 #endif
03651
03652 if (prev_def) {
03653 v->mtype = prev_def->mtype;
03654 v->has_offset = prev_def->has_offset;
03655 v->ty = prev_def->ty;
03656 v->vtree = prev_def->vtree ? WN_COPY_Tree(prev_def->vtree) : NULL;
03657 v->vtreex = prev_def->vtreex ? WN_COPY_Tree(prev_def->vtreex) : NULL;
03658 v->new_st = prev_def->new_st;
03659 v->new_offset = prev_def->new_offset;
03660 if (prev_def->vtype == VAR_LASTLOCAL)
03661 prev_def->is_last_and_firstprivate = TRUE;
03662
03663 } else if (ST_class(old_st) != CLASS_PREG) {
03664
03665 ty = ST_type(old_st);
03666 #ifdef KEY // bug 7259 and 8076
03667 if ((TY_kind(ty) == KIND_STRUCT) &&
03668 (vtype == VAR_REDUCTION_SCALAR || vtype == VAR_REDUCTION_ARRAY))
03669 ty = FLD_type(TY_fld(ty));
03670 #endif
03671 if ((TY_kind(ty) == KIND_POINTER) &&
03672 ((v->is_static_array) || (vtype == VAR_REDUCTION_ARRAY)))
03673 #ifdef KEY //bug 11661
03674 {
03675 #endif
03676 ty = TY_pointed(ty);
03677 #ifdef KEY //bug 11661: for structure, we need the field type
03678 if (TY_kind(ty) == KIND_STRUCT && vtype == VAR_REDUCTION_ARRAY)
03679 ty = FLD_type(TY_fld(ty));
03680 }
03681 #endif
03682
03683 if ((TY_kind(ty) == KIND_ARRAY) && (vtype == VAR_REDUCTION_ARRAY))
03684 ty = TY_etype(ty);
03685 if ((vtype == VAR_REDUCTION_ARRAY_OMP) && (TY_kind(ty) == KIND_POINTER)
03686 && (TY_kind(TY_pointed(ty)) == KIND_ARRAY))
03687 {
03688 ty = TY_pointed(ty);
03689
03690
03691
03692
03693 }
03694
03695 localname = (char *) alloca(strlen(ST_name(old_st)) + 32);
03696
03697 if (strncmp(ST_name(old_st), "__mplocal_", 10) == 0)
03698 sprintf ( localname, "__mplocalx_%s", &ST_name(old_st)[10] );
03699 else if (strncmp(ST_name(old_st), "__mplocalfe_", 12) == 0)
03700 sprintf ( localname, "__mplocalfex_%s", &ST_name(old_st)[12] );
03701 else if (strncmp(ST_name(old_st), "__mptemp_", 9) == 0)
03702 sprintf ( localname, "__mptempx_%s", &ST_name(old_st)[9] );
03703 else
03704 sprintf ( localname, "__mplocal_%s", ST_name(old_st) );
03705
03706 if (v->is_non_pod && orphaned) {
03707
03708
03709
03710 sym = NULL;
03711
03712 } else {
03713 sym = NULL;
03714 #ifdef KEY
03715 INT16 i;
03716 ST *symbol;
03717 WN *thread_priv_prag = NULL;
03718 WN *matched_pragma = NULL;
03719 if (reference_block) {
03720 thread_priv_prag = WN_first(reference_block);
03721 if (thread_priv_prag) {
03722 while (thread_priv_prag) {
03723 if (WN_opcode(thread_priv_prag) == OPC_PRAGMA &&
03724 WN_pragma(thread_priv_prag) == WN_PRAGMA_THREADPRIVATE) {
03725 if (WN_pragma_arg1(thread_priv_prag) == ST_st_idx(old_st)){
03726 matched_pragma = thread_priv_prag;
03727 break;
03728 }
03729 }
03730 thread_priv_prag = WN_next(thread_priv_prag);
03731 }
03732
03733 thread_priv_prag = WN_first(reference_block);
03734 while (!matched_pragma && thread_priv_prag) {
03735 if (WN_opcode(thread_priv_prag) == OPC_PRAGMA &&
03736 WN_pragma(thread_priv_prag) == WN_PRAGMA_THREADPRIVATE){
03737 FOREACH_SYMBOL (CURRENT_SYMTAB, symbol, i) {
03738 if (symbol == ST_ptr(WN_pragma_arg1(thread_priv_prag)) &&
03739 strcmp(localname, ST_name(symbol)) == 0) {
03740 sym = symbol;
03741 break;
03742 }
03743 }
03744 if (!sym)
03745 break;
03746 }
03747 thread_priv_prag = WN_next(thread_priv_prag);
03748 }
03749 }
03750 }
03751
03752
03753
03754
03755 if (!sym)
03756 for (INT it = 0; it < localized_var_vect.size(); it++)
03757 {
03758 if (localized_var_vect[it].Thdprv_ptr() == ST_st_idx (old_st))
03759 {
03760 sym = ST_ptr (localized_var_vect[it].Thdprv_local());
03761 break;
03762 }
03763 }
03764 #endif
03765
03766 if (!sym) {
03767 sym = New_ST (CURRENT_SYMTAB);
03768 ST_Init (sym,
03769 Save_Str (localname),
03770 CLASS_VAR,
03771 SCLASS_AUTO,
03772 EXPORT_LOCAL,
03773 ty);
03774
03775 if (ST_addr_saved(old_st))
03776 Set_ST_addr_saved(sym);
03777 if (ST_addr_passed(old_st))
03778 Set_ST_addr_passed(sym);
03779 }
03780 #ifdef KEY
03781 {
03782
03783 WN *prag = WN_first(WN_func_pragmas(PU_Info_tree_ptr(Current_PU_Info)));
03784 while (prag)
03785 {
03786 if (WN_opcode (prag) == OPC_PRAGMA &&
03787 WN_pragma (prag) == WN_PRAGMA_THREADPRIVATE &&
03788 WN_pragma_arg1 (prag) == ST_st_idx (old_st))
03789 {
03790 Localized_thdprv_var v (WN_pragma_arg1 (prag), ST_st_idx (sym));
03791
03792 localized_var_vect.push_back (v);
03793 WN_pragma_arg1 (prag) = ST_st_idx (sym);
03794 break;
03795 }
03796 prag = WN_next (prag);
03797 }
03798 }
03799 if (matched_pragma)
03800 WN_pragma_arg1(matched_pragma) = ST_st_idx(sym);
03801 #endif
03802
03803
03804
03805
03806
03807
03808
03809 if (v->is_dynamic_array) {
03810 Set_ST_pt_to_unique_mem(sym);
03811 Set_ST_pt_to_compiler_generated_mem(sym);
03812 }
03813
03814 if (Debug_Level > 0) {
03815
03816
03817 #ifndef KEY
03818 dst = Find_DST_From_ST( old_st, ppuinfo );
03819 #else // bug 5473
03820 if (ppuinfo) dst = Find_DST_From_ST( old_st, ppuinfo );
03821 else dst = DST_INVALID_IDX;
03822 #endif
03823
03824
03825
03826
03827 if (!DST_IS_NULL(dst))
03828 Create_New_DST( dst, sym, !orphaned );
03829 }
03830 }
03831
03832 if (TY_kind(ty) == KIND_ARRAY) {
03833 v->mtype = TY_mtype(TY_etype(ty));
03834 v->has_offset = (vtype != VAR_LASTLOCAL) && (vtype != VAR_LOCAL) &&
03835 (vtype != VAR_FIRSTPRIVATE) && (vtype != VAR_REDUCTION_ARRAY_OMP);
03836 } else if (TY_kind(ty) == KIND_STRUCT) {
03837 v->mtype = TY_mtype(ty);
03838 v->has_offset = FALSE;
03839 } else if (v->is_dynamic_array) {
03840 v->mtype = TY_mtype(TY_AR_etype(TY_pointed(ty)));
03841 v->has_offset = FALSE;
03842 } else {
03843 v->mtype = TY_mtype(ty);
03844 v->has_offset = TRUE;
03845 }
03846 v->ty = ty;
03847 v->new_st = sym;
03848 v->new_offset = 0;
03849
03850 if ((v->is_static_array) && (vtree == NULL)) {
03851 v->vtree = WN_RLdid ( Promote_Type(Pointer_type), Pointer_type,
03852 old_offset, old_st, ST_type(old_st) );
03853 v->vtreex = WN_Create ( (Pointer_Size == 4) ? OPC_U4ARRAY : OPC_U8ARRAY,
03854 3 );
03855 WN_element_size(v->vtreex) = Pointer_Size;
03856 WN_kid0(v->vtreex) = WN_RLdid ( Promote_Type(Pointer_type), Pointer_type,
03857 old_offset, old_st, ST_type(old_st) );
03858 WN_kid1(v->vtreex) = WN_Intconst ( MTYPE_I4, 0 );
03859 WN_kid2(v->vtreex) = WN_Intconst ( MTYPE_I4, 0 );
03860 }
03861
03862 if (v->is_dynamic_array &&
03863 Vla_Needs_Alloca(v->orig_st) &&
03864 !v->is_non_pod) {
03865 if (*alloca_blockp == NULL)
03866 *alloca_blockp = WN_CreateBlock ( );
03867 WN_INSERT_BlockLast(*alloca_blockp,
03868 Gen_Auto_Alloca(v->new_st, v->new_offset, v->ty,
03869 Calculate_Array_Size(old_st, TY_pointed(ty))));
03870 }
03871
03872 } else {
03873 v->mtype = ST_btype(old_st);
03874 v->has_offset = TRUE;
03875 v->ty = ST_type(old_st);
03876 v->new_st = old_st;
03877 v->new_offset = old_offset;
03878
03879 }
03880
03881 if (vtype == VAR_FIRSTPRIVATE && firstprivate_blockp &&
03882 !v->is_non_pod) {
03883 if (*firstprivate_blockp == NULL)
03884 *firstprivate_blockp = WN_CreateBlock ( );
03885 WN_INSERT_BlockLast(*firstprivate_blockp,
03886 Gen_MP_Load_Store(v->orig_st, v->orig_offset,
03887 v->new_st, v->new_offset,
03888 v->is_dynamic_array));
03889 }
03890
03891
03892 if (vtype == VAR_REDUCTION_SCALAR ||
03893 vtype == VAR_REDUCTION_ARRAY ||
03894 vtype == VAR_REDUCTION_ARRAY_OMP) {
03895 TYPE_ID rtype, dtype = MTYPE_V;
03896
03897
03898
03899
03900
03901 if (opr == OPERATOR_UNKNOWN) {
03902 char *redvar_name = (char *) alloca(strlen(ST_name(v->orig_st)) + 32);
03903
03904 sprintf(redvar_name, "%s %s",
03905 vtree ? "element of array" : "variable",
03906 ST_name(v->orig_st));
03907 ErrMsg(EC_MPLOWER_red_not_found, redvar_name);
03908 }
03909
03910
03911 if (v->mtype == MTYPE_I1 || v->mtype == MTYPE_I2)
03912 rtype = MTYPE_I4;
03913 else if (v->mtype == MTYPE_U1 || v->mtype == MTYPE_U2)
03914 rtype = MTYPE_U4;
03915 else
03916 rtype = v->mtype;
03917
03918 switch (opr) {
03919 case OPR_LAND:
03920 case OPR_LIOR:
03921 if (v->mtype == MTYPE_I8) {
03922
03923 rtype = MTYPE_I4;
03924 }
03925 break;
03926
03927 case OPR_EQ:
03928 case OPR_NE:
03929 if (rtype == MTYPE_I8) {
03930 dtype = MTYPE_I8;
03931
03932 rtype = MTYPE_I4;
03933 } else {
03934 dtype = rtype;
03935 }
03936 break;
03937
03938 case OPR_CAND:
03939 case OPR_CIOR:
03940
03941 rtype = MTYPE_I4;
03942 break;
03943
03944 default:
03945 break;
03946 }
03947
03948 v->reduction_opr = opr;
03949 v->reduction_opc = OPCODE_make_op(opr, rtype, dtype);
03950 } else {
03951 v->reduction_opr = OPERATOR_UNKNOWN;
03952 v->reduction_opc = OPCODE_UNKNOWN;
03953 }
03954 }
03955
03956
03957
03958
03959
03960
03961
03962 static void
03963 Verify_No_Pregs_In_Tree(WN *tree)
03964 {
03965 WN_ITER *it = WN_WALK_TreeIter(tree);
03966
03967 while (it) {
03968 WN *wn = it->wn;
03969
03970 OPERATOR opr = WN_operator(wn);
03971
03972 if (OPERATOR_has_sym(opr) && OPERATOR_has_offset(opr) && WN_st(wn) &&
03973 ST_class(WN_st(wn)) == CLASS_PREG &&
03974 !Preg_Is_Dedicated(WN_offsetx(wn)))
03975 Fail_FmtAssertion("invalid preg reference in worksharing scope pragma");
03976
03977 it = WN_WALK_TreeNext(it);
03978 }
03979 }
03980 #ifdef KEY
03981
03982
03983 static ST*
03984 Create_Copyfunc(ST *struct_st)
03985 {
03986 SYMTAB_IDX cp_psymtab = CURRENT_SYMTAB;
03987 PU_Info *cp_ppuinfo = Current_PU_Info;
03988 WN_MAP_TAB *cp_pmaptab = Current_Map_Tab;
03989 WN_MAP_TAB *cp_cmaptab = cmaptab;
03990 ST *cp_parallel_proc = parallel_proc, *swap_proc;
03991 SYMTAB_IDX cp_csymtab;
03992 INT32 cp_func_level;
03993
03994 const char *construct_type_str = "cp_thunk";
03995 TY_IDX &func_ty_idx = mpregion_ty;
03996 char temp_str[64];
03997
03998 if (func_ty_idx == TY_IDX_ZERO) {
03999
04000
04001 TY& ty = New_TY(func_ty_idx);
04002 sprintf(temp_str, ".%s", construct_type_str);
04003 TY_Init(ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str(temp_str));
04004 Set_TY_align(func_ty_idx, 1);
04005
04006 TYLIST_IDX parm_idx;
04007 TYLIST& parm_list = New_TYLIST(parm_idx);
04008 Set_TY_tylist(ty, parm_idx);
04009 Set_TYLIST_type(parm_list, Be_Type_Tbl(MTYPE_V));
04010
04011
04012 Set_TYLIST_type(New_TYLIST(parm_idx),
04013 Be_Type_Tbl(Pointer_type));
04014 Set_TYLIST_type(New_TYLIST(parm_idx),
04015 Be_Type_Tbl(Pointer_type));
04016
04017 Set_TYLIST_type(New_TYLIST(parm_idx), TY_IDX_ZERO);
04018
04019
04020 TY_IDX ptr_ty_idx;
04021 TY &ptr_ty = New_TY(ptr_ty_idx);
04022 sprintf(temp_str, ".%s_ptr", construct_type_str);
04023 TY_Init(ptr_ty, Pointer_Size, KIND_POINTER, Pointer_Mtype,
04024 Save_Str(temp_str));
04025 Set_TY_pointed(ptr_ty, func_ty_idx);
04026 }
04027
04028 PU_IDX pu_idx;
04029 PU& pu = New_PU(pu_idx);
04030 PU_Init(pu, func_ty_idx, CURRENT_SYMTAB);
04031
04032 Set_PU_no_inline(pu);
04033 Set_PU_is_nested_func(pu);
04034 Set_PU_mp(pu);
04035 if (PU_c_lang(Current_PU_Info_pu()))
04036 Set_PU_c_lang(pu);
04037 if (PU_cxx_lang(Current_PU_Info_pu()))
04038 Set_PU_cxx_lang(pu);
04039 if (PU_f77_lang(Current_PU_Info_pu()))
04040 Set_PU_f77_lang(pu);
04041 if (PU_f90_lang(Current_PU_Info_pu()))
04042 Set_PU_f90_lang(pu);
04043 if (PU_java_lang(Current_PU_Info_pu()))
04044 Set_PU_java_lang(pu);
04045
04046 Set_FILE_INFO_has_mp(File_info);
04047
04048 char *st_name = (char *) alloca(strlen(construct_type_str) + 32);
04049 sprintf ( st_name, "__%s_%d", construct_type_str, ST_st_idx(struct_st));
04050
04051 parallel_proc = New_ST(GLOBAL_SYMTAB);
04052 ST_Init(parallel_proc,
04053 Save_Str (st_name),
04054 CLASS_FUNC,
04055 SCLASS_TEXT,
04056 EXPORT_LOCAL,
04057 pu_idx);
04058 Set_ST_addr_passed(parallel_proc);
04059
04060 Allocate_Object ( parallel_proc );
04061
04062 New_Scope(CURRENT_SYMTAB + 1,
04063 Malloc_Mem_Pool,
04064 TRUE);
04065 cp_csymtab = CURRENT_SYMTAB;
04066 cp_func_level = CURRENT_SYMTAB;
04067 Scope_tab[cp_csymtab].st = parallel_proc;
04068
04069 Set_PU_lexical_level(pu, CURRENT_SYMTAB);
04070 Create_Func_DST ( st_name );
04071
04072 for (UINT32 i = 1; i < PREG_Table_Size(cp_psymtab); i++) {
04073 PREG_IDX preg_idx;
04074 PREG &preg = New_PREG(cp_csymtab, preg_idx);
04075
04076 Set_PREG_name_idx(preg,
04077 PREG_name_idx((*Scope_tab[cp_psymtab].preg_tab)[preg_idx]));
04078 }
04079 ST *arg_src = New_ST( CURRENT_SYMTAB );
04080 ST_Init (arg_src,
04081 Save_Str ( "__ompv_src_a" ),
04082 CLASS_VAR,
04083 SCLASS_FORMAL,
04084 EXPORT_LOCAL,
04085 Be_Type_Tbl( Pointer_type ));
04086 Set_ST_is_value_parm( arg_src );
04087
04088 ST *arg_dst = New_ST( CURRENT_SYMTAB );
04089 ST_Init( arg_dst,
04090 Save_Str( "__ompv_dst_a" ),
04091 CLASS_VAR,
04092 SCLASS_FORMAL,
04093 EXPORT_LOCAL,
04094 Be_Type_Tbl( Pointer_type ));
04095 Set_ST_is_value_parm( arg_dst );
04096
04097 WN *func_body = WN_CreateBlock();
04098 WN *func_entry = WN_CreateEntry(2, parallel_proc,
04099 func_body,
04100 WN_CreateBlock(),
04101 WN_CreateBlock());
04102
04103 WN_linenum(func_entry) = line_number;
04104 WN_kid0(func_entry) = WN_CreateIdname ( 0, arg_src );
04105 WN_kid1(func_entry) = WN_CreateIdname ( 0, arg_dst );
04106 WN_linenum(func_entry) = line_number;
04107
04108 FLD_HANDLE fld;
04109 fld = TY_flist(Ty_Table[ST_type(struct_st)]);
04110 WN *value, *addr, *istore;
04111 TYPE_ID type;
04112 for (; !fld.Is_Null (); fld = FLD_next(fld)){
04113 TY& ty = Ty_Table [FLD_type (fld)];
04114 TY *pty = &ty;
04115 TY_IDX pty_idx = TY_pointed(*pty);
04116 OPCODE addr_load_opc = OPCODE_make_op(OPR_ILOAD, Pointer_type, Pointer_type);
04117 if (TY_kind(pty_idx) != KIND_ARRAY){
04118 type = TY_mtype(pty_idx);
04119 OPCODE load_opc = OPCODE_make_op(OPR_ILOAD,type,type);
04120 value = WN_CreateIload(load_opc, 0,
04121 Be_Type_Tbl(type),
04122 Make_Pointer_Type(Be_Type_Tbl(type),FALSE),
04123 WN_CreateIload(addr_load_opc, FLD_ofst(fld),
04124 Be_Type_Tbl(Pointer_type),
04125 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04126 WN_Ldid(Pointer_type, 0, arg_src, ST_type(arg_src))));
04127 istore = WN_CreateIstore(OPCODE_make_op(OPR_ISTORE,MTYPE_V,type),
04128 0,
04129 Make_Pointer_Type(Be_Type_Tbl(type),FALSE),
04130 value,
04131 WN_CreateIload(addr_load_opc, FLD_ofst(fld),
04132 Be_Type_Tbl(Pointer_type),
04133 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04134 WN_Ldid(Pointer_type, 0, arg_dst, ST_type(arg_dst))));
04135 WN_INSERT_BlockLast(func_body, istore);
04136 }
04137 else{
04138
04139 WN *call = Transform_To_Memcpy(WN_CreateIload(addr_load_opc, FLD_ofst(fld),
04140 Be_Type_Tbl(Pointer_type),
04141 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04142 WN_Ldid(Pointer_type, 0, arg_dst, ST_type(arg_dst))),
04143 WN_CreateIload(addr_load_opc, FLD_ofst(fld),
04144 Be_Type_Tbl(Pointer_type),
04145 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04146 WN_Ldid(Pointer_type, 0, arg_src, ST_type(arg_src))),
04147 0,
04148 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04149 Make_Pointer_Type(Be_Type_Tbl(Pointer_type),FALSE),
04150 WN_CreateIntconst (OPC_U4INTCONST,TY_size(pty_idx)));
04151 WN_INSERT_BlockLast(func_body, call);
04152 }
04153 }
04154 WN *wn = WN_CreateReturn ( );
04155 WN_linenum(wn) = line_number;
04156 WN_INSERT_BlockLast ( func_body, wn );
04157
04158 PU_Info *copy_pu = TYPE_MEM_POOL_ALLOC ( PU_Info, Malloc_Mem_Pool );
04159 PU_Info_init ( copy_pu );
04160 Set_PU_Info_tree_ptr (copy_pu, func_entry );
04161
04162
04163 PU_Info_proc_sym(copy_pu) = ST_st_idx(parallel_proc);
04164 PU_Info_maptab(copy_pu) = cp_cmaptab = WN_MAP_TAB_Create(MEM_pu_pool_ptr);
04165 PU_Info_pu_dst(copy_pu) = nested_dst;
04166 Set_PU_Info_state(copy_pu, WT_SYMTAB, Subsect_InMem);
04167 Set_PU_Info_state(copy_pu, WT_TREE, Subsect_InMem);
04168 Set_PU_Info_state(copy_pu, WT_PROC_SYM, Subsect_InMem);
04169 Set_PU_Info_flags(copy_pu, PU_IS_COMPILER_GENERATED);
04170
04171 Set_PU_Info_symtab_ptr(copy_pu, NULL);
04172 Save_Local_Symtab(cp_csymtab, copy_pu);
04173
04174 if (Cur_PU_Feedback) {
04175 parallel_pu_fb = CXX_NEW(FEEDBACK(func_entry,
04176 MEM_pu_nz_pool_ptr,
04177 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
04178 cp_cmaptab),
04179 MEM_pu_nz_pool_ptr);
04180 Set_PU_Info_state(copy_pu, WT_FEEDBACK, Subsect_InMem);
04181 Set_PU_Info_feedback_ptr(copy_pu, parallel_pu_fb);
04182 FB_Transfer(Cur_PU_Feedback, parallel_pu_fb, stmt_block);
04183 }
04184
04185 RID *root_rid = RID_Create ( 0, 0, func_entry );
04186 RID_type(root_rid) = RID_TYPE_func_entry;
04187 Set_PU_Info_regions_ptr ( copy_pu, root_rid );
04188 Is_True(PU_Info_regions_ptr(copy_pu) != NULL,
04189 ("Create_Copythunk, NULL root RID"));
04190
04191 PU_Info *tpu = PU_Info_child(Current_PU_Info);
04192
04193
04194 if (tpu && PU_Info_state(tpu, WT_SYMTAB) == Subsect_InMem &&
04195 PU_mp(PU_Info_pu(tpu)) ) {
04196 PU_Info *npu;
04197
04198 while ((npu = PU_Info_next(tpu)) &&
04199 PU_Info_state(npu, WT_SYMTAB) == Subsect_InMem &&
04200 PU_mp(PU_Info_pu(npu)) )
04201 tpu = npu;
04202
04203 PU_Info_next(tpu) = copy_pu;
04204 PU_Info_next(copy_pu) = npu;
04205 } else {
04206 PU_Info_child(Current_PU_Info) = copy_pu;
04207 PU_Info_next(copy_pu) = tpu;
04208 }
04209
04210
04211
04212
04213 Current_PU_Info = cp_ppuinfo;
04214 Current_pu = &Current_PU_Info_pu();
04215 Current_Map_Tab = cp_pmaptab;
04216 Transfer_Maps ( cp_pmaptab, cp_cmaptab, func_body,
04217 PU_Info_regions_ptr(Current_PU_Info) );
04218
04219 Current_Map_Tab = cp_cmaptab;
04220
04221
04222 Set_PU_Info_depgraph_ptr(copy_pu,NULL);
04223 Current_Map_Tab = cp_pmaptab;
04224
04225 CURRENT_SYMTAB = cp_psymtab;
04226 Add_DST_variable ( arg_src, nested_dst, line_number, DST_INVALID_IDX );
04227 Add_DST_variable ( arg_dst, nested_dst, line_number, DST_INVALID_IDX );
04228
04229 swap_proc = parallel_proc;
04230 parallel_proc = cp_parallel_proc;
04231 return swap_proc;
04232 }
04233
04234
04235
04236
04237
04238 static void
04239 Gen_MP_Copyprivate(WN *copyprivates, WN **copyprivate_blockp,
04240 WN *ldid_lock)
04241 {
04242 WN *wnx;
04243 FLD_HANDLE fld;
04244 FLD *next;
04245 ST *st, *fld_st;
04246
04247 #ifndef TARG_NVISA
04248 BOOL target_32bit = Is_Target_32bit();
04249 #else
04250 BOOL target_32bit = FALSE;
04251 #endif
04252
04253
04254 INT32 count = 0;
04255 for (wnx = copyprivates; wnx; wnx = WN_next(wnx),count++);
04256
04257 TY_IDX struct_ty_idx;
04258 TY& struct_ty = New_TY(struct_ty_idx);
04259 TY_Init(struct_ty, target_32bit ? 4*count : 8*count,
04260 KIND_STRUCT, MTYPE_M, STR_IDX_ZERO);
04261 Set_TY_align(struct_ty_idx, MTYPE_align_req(Pointer_type));
04262
04263 INT32 offset = 0;
04264 for (wnx = copyprivates; wnx; wnx = WN_next(wnx)){
04265 fld_st = WN_st(wnx);
04266 fld = New_FLD ();
04267 if (wnx == copyprivates)
04268 Set_TY_fld(struct_ty, fld);
04269 FLD_Init (fld, Save_Str(ST_name(fld_st)),
04270 Make_Pointer_Type (TY_IDX(ST_type(fld_st))), offset);
04271 offset += target_32bit ? 4 : 8;
04272 }
04273 Set_FLD_last_field (fld);
04274
04275 char st_name[32];
04276 sprintf ( st_name, "__mp_cpprv_%d", ST_st_idx(fld_st) );
04277 st = New_ST(CURRENT_SYMTAB);
04278 ST_Init (st,
04279 Save_Str(st_name),
04280 CLASS_VAR,
04281 SCLASS_AUTO,
04282 EXPORT_LOCAL,
04283 struct_ty_idx);
04284 Set_ST_base (st, st);
04285
04286 WN *wn;
04287
04288
04289 fld = TY_flist(Ty_Table[ST_type(st)]);
04290
04291 for (wnx = copyprivates; wnx; wnx = WN_next(wnx), fld = FLD_next(fld))
04292 {
04293 TY_IDX ty = FLD_type(fld);
04294 wn = WN_Stid ( TY_mtype(ty), FLD_ofst(fld), st,
04295 ty, WN_Lda (Pointer_type,0,WN_st(wnx)) );
04296 #ifdef KEY // bug 8764
04297 Set_ST_addr_saved(WN_st(wnx));
04298 #endif
04299 WN_linenum(wn) = line_number;
04300 WN_INSERT_BlockLast(*copyprivate_blockp, wn);
04301 }
04302
04303
04304 wn = WN_Create ( OPC_VCALL, 3 );
04305 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_COPYPRIVATE);
04306
04307 WN_Set_Call_Non_Data_Mod ( wn );
04308 WN_Set_Call_Non_Data_Ref ( wn );
04309 WN_Set_Call_Non_Parm_Mod ( wn );
04310 WN_Set_Call_Non_Parm_Ref ( wn );
04311 WN_Set_Call_Parm_Mod ( wn );
04312 WN_Set_Call_Parm_Ref ( wn );
04313 WN_linenum(wn) = line_number;
04314 WN_kid0(wn) = WN_CreateParm ( MTYPE_I4,
04315 ldid_lock,
04316 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE );
04317
04318 WN_kid1(wn) = WN_CreateParm (Pointer_type,
04319 WN_Lda(Pointer_type, 0, st),
04320 Make_Pointer_Type ( ST_type(st),FALSE ),
04321 WN_PARM_BY_REFERENCE );
04322
04323
04324 Push_Some_Globals( );
04325 ST *copyproc = Create_Copyfunc(st);
04326 Pop_Some_Globals( );
04327
04328 WN_kid2(wn) = WN_CreateParm (Pointer_type,
04329 WN_Lda(Pointer_type, 0, copyproc),
04330 Make_Pointer_Type ( ST_pu_type(copyproc),FALSE ),
04331 WN_PARM_BY_REFERENCE );
04332
04333 WN_INSERT_BlockLast(*copyprivate_blockp, wn);
04334 }
04335 #endif
04336
04337
04338
04339
04340
04341
04342
04343
04344 static void
04345 Create_Local_Variables ( VAR_TABLE * vtab, WN * reductions,
04346 WN * lastlocals, WN * locals,
04347 WN * firstprivates,
04348 WN **firstprivate_blockp,
04349 WN * lastthread,
04350 WN ** alloca_blockp )
04351 {
04352 WN *l;
04353 OPERATOR opr;
04354 VAR_TABLE *v = vtab;
04355 BOOL is_non_combined_worksharing = FALSE;
04356
04357 switch (mpt) {
04358 case MPP_SINGLE:
04359 case MPP_ORPHANED_SINGLE:
04360 case MPP_PDO:
04361 case MPP_ORPHANED_PDO:
04362 #ifdef KEY
04363 case MPP_WORKSHARE:
04364 case MPP_ORPHANED_WORKSHARE:
04365 #endif
04366 is_non_combined_worksharing = TRUE;
04367 break;
04368 case MPP_PARALLEL_DO:
04369 case MPP_PARALLEL_REGION:
04370 #ifdef KEY
04371 case MPP_ORPHAN:
04372 #endif
04373 break;
04374 default:
04375 Fail_FmtAssertion("illegal construct, mpt == %d", (INT) mpt);
04376 }
04377
04378 #ifdef Is_True_On
04379 if (is_non_combined_worksharing) {
04380
04381
04382
04383
04384
04385 WN *ll[] = { reductions, lastlocals, firstprivates, NULL };
04386 INT i;
04387
04388 for (i = 0; ll[i]; i++)
04389 for (l = ll[i]; l; l = WN_next(l))
04390 Verify_No_Pregs_In_Tree(l);
04391 }
04392 #endif
04393
04394
04395 for (l = reductions; l; l = WN_next(l)) {
04396 if (WN_opcode(l) == OPC_PRAGMA) {
04397 VAR_TYPE reduction_var_type = VAR_REDUCTION_SCALAR;
04398 if( WN_pragma_omp(l) && WN_st(l) &&
04399 Is_Kind_Array(WN_st(l)) == TRUE)
04400
04401 reduction_var_type = VAR_REDUCTION_ARRAY_OMP;
04402
04403 Localize_Variable( v, reduction_var_type,
04404 (OPERATOR) WN_pragma_arg2(l), NULL, WN_st(l),
04405 WN_offsetx(l), firstprivate_blockp, alloca_blockp,
04406 NULL );
04407 v++;
04408 } else {
04409 opr = WN_operator(WN_kid0(l));
04410 if ((opr == OPR_LDA) || (opr == OPR_LDID)) {
04411 Localize_Variable ( v, VAR_REDUCTION_SCALAR,
04412 (OPERATOR) WN_pragma_arg2(l), NULL,
04413 WN_st(WN_kid0(l)), WN_offsetx(WN_kid0(l)),
04414 firstprivate_blockp, alloca_blockp, NULL );
04415 v++;
04416 } else if (opr == OPR_ARRAY) {
04417 Localize_Variable ( v, VAR_REDUCTION_ARRAY,
04418 (OPERATOR) WN_pragma_arg2(l),
04419 WN_COPY_Tree ( WN_kid0(l) ),
04420 WN_st(WN_kid0(WN_kid0(l))),
04421 WN_offsetx(WN_kid0(WN_kid0(l))),
04422 firstprivate_blockp, alloca_blockp, NULL );
04423 v++;
04424 #ifdef KEY // bug 9112 : handle the extra offset specified by an ADD
04425 } else if (opr == OPR_ADD &&
04426 WN_operator(WN_kid0(WN_kid0(l))) == OPR_ARRAY) {
04427 INT ofst = WN_const_val(WN_kid1(WN_kid0(l)));
04428 Localize_Variable ( v, VAR_REDUCTION_ARRAY,
04429 (OPERATOR) WN_pragma_arg2(l),
04430 WN_COPY_Tree ( WN_kid0(WN_kid0(l)) ),
04431 WN_st(WN_kid0(WN_kid0(WN_kid0(l)))),
04432 WN_offsetx(WN_kid0(WN_kid0(WN_kid0(l))))+ofst,
04433 firstprivate_blockp, alloca_blockp, NULL );
04434 v++;
04435 #endif
04436 } else {
04437 Fail_FmtAssertion ( "invalid reduction directive" );
04438 }
04439 }
04440 }
04441
04442
04443 for (l = lastlocals; l; l = WN_next(l)) {
04444 if (WN_pragma_arg2(l) & SHARED_DEADOUT)
04445 Localize_Variable ( v, VAR_LOCAL, OPERATOR_UNKNOWN, NULL, WN_st(l),
04446 WN_offsetx(l), firstprivate_blockp,
04447 alloca_blockp, NULL );
04448 else
04449 Localize_Variable ( v, VAR_LASTLOCAL, OPERATOR_UNKNOWN, NULL,
04450 WN_st(l), WN_offsetx(l), firstprivate_blockp,
04451 alloca_blockp, NULL );
04452 v++;
04453 }
04454
04455
04456 for (l = locals; l; l = WN_next(l)) {
04457 Localize_Variable ( v, VAR_LOCAL, OPERATOR_UNKNOWN, NULL, WN_st(l),
04458 WN_offsetx(l), firstprivate_blockp, alloca_blockp,
04459 NULL );
04460 if (lastthread && (v->orig_st == WN_st(lastthread)) &&
04461 (v->orig_offset == WN_offsetx(lastthread))) {
04462 WN_st_idx(lastthread) = ST_st_idx(v->new_st);
04463 WN_set_offsetx(lastthread, v->new_offset);
04464 }
04465 v++;
04466 }
04467
04468
04469 for (l = firstprivates; l; l = WN_next(l)) {
04470
04471 VAR_TABLE *llv = vtab;
04472
04473 for ( ; llv->orig_st; llv++)
04474 if (WN_st(l) == llv->orig_st &&
04475 (!llv->has_offset || WN_offsetx(l) == llv->orig_offset)) {
04476
04477 Is_True(llv->vtype == VAR_LASTLOCAL || llv->vtype == VAR_LOCAL,
04478 ("impossible combination of variable types"));
04479 break;
04480 }
04481
04482 if (!llv->orig_st)
04483 llv = NULL;
04484
04485 Localize_Variable ( v, VAR_FIRSTPRIVATE, OPERATOR_UNKNOWN, NULL,
04486 WN_st(l), WN_offsetx(l), firstprivate_blockp,
04487 alloca_blockp, llv );
04488 if (lastthread && (v->orig_st == WN_st(lastthread)) &&
04489 (v->orig_offset == WN_offsetx(lastthread))) {
04490 WN_st_idx(lastthread) = ST_st_idx(v->new_st);
04491 WN_set_offsetx(lastthread, v->new_offset);
04492 }
04493 v++;
04494 }
04495
04496 }
04497
04498
04499
04500
04501
04502
04503
04504 static OPCODE
04505 Make_Final_Reduction_Op ( OPCODE op )
04506 {
04507 OPERATOR opr = OPCODE_operator(op);
04508
04509 if (opr == OPR_SUB)
04510 return (OPCODE_make_op ( OPR_ADD, OPCODE_rtype(op), MTYPE_V ));
04511 else if (opr == OPR_DIV)
04512 return (OPCODE_make_op ( OPR_MPY, OPCODE_rtype(op), MTYPE_V ));
04513 else
04514 return (op);
04515 }
04516
04517
04518
04519
04520
04521
04522
04523 static void
04524 Localize_INITVKIND_SYMOFF(INITV_IDX new_idx, INITV_IDX old_idx, VAR_TABLE *v )
04525 {
04526 Is_True(new_idx !=0, ("null new_idx"));
04527 Is_True(old_idx !=0, ("null old_idx"));
04528
04529 INITV &new_initv = Initv_Table[new_idx];
04530 INITV &old_initv = Initv_Table[old_idx];
04531
04532 BOOL same_initv = new_idx == old_idx;
04533 INITV_IDX orig_next;
04534 if (same_initv)
04535 orig_next = INITV_next(old_idx);
04536
04537 Is_True(INITV_kind(new_initv) == INITVKIND_SYMOFF,
04538 ("wrong kind of new_initv"));
04539 Is_True(INITV_kind(old_initv) == INITVKIND_SYMOFF,
04540 ("wrong kind of old_initv"));
04541
04542 INITV_Set_SYMOFF(new_initv, INITV_repeat1(old_initv), INITV_st(old_initv),
04543 INITV_ofst(old_initv));
04544 if (same_initv)
04545 Set_INITV_next(new_idx, orig_next);
04546
04547 for ( ; v->orig_st; v++) {
04548 if (ST_st_idx(*v->orig_st) == INITV_st(old_initv) &&
04549 (!v->has_offset || (v->orig_offset == INITV_ofst(old_initv))) ) {
04550 INITV_Set_SYMOFF(new_initv, INITV_repeat1(new_initv),
04551 ST_st_idx(*v->new_st),
04552 v->has_offset ? v->new_offset : INITV_ofst(new_initv));
04553 if (same_initv)
04554 Set_INITV_next(new_idx, orig_next);
04555 break;
04556 }
04557 }
04558 }
04559
04560
04561
04562
04563
04564
04565 static void
04566 Localize_All_INITVKIND_SYMOFFs(INITO_IDX obj_idx, VAR_TABLE *vtab )
04567 {
04568 Is_True(obj_idx !=0, ("null obj_idx"));
04569
04570 STACK<INITV_IDX> initv_stack(Malloc_Mem_Pool);
04571 INITV_IDX val_idx = INITO_val(obj_idx);
04572
04573 while (val_idx) {
04574 INITVKIND k = INITV_kind(val_idx);
04575 switch (k) {
04576 case INITVKIND_SYMOFF:
04577 Localize_INITVKIND_SYMOFF(val_idx, val_idx, vtab);
04578 val_idx = INITV_next(val_idx);
04579 break;
04580
04581 case INITVKIND_ZERO:
04582 case INITVKIND_ONE:
04583 case INITVKIND_VAL:
04584 case INITVKIND_PAD:
04585 case INITVKIND_SYMDIFF:
04586 case INITVKIND_SYMDIFF16:
04587 case INITVKIND_LABEL:
04588 val_idx = INITV_next(val_idx);
04589 break;
04590
04591 case INITVKIND_BLOCK:
04592 initv_stack.Push(val_idx);
04593 val_idx = INITV_blk(val_idx);
04594 break;
04595
04596 default:
04597 Fail_FmtAssertion ( "unknown INITV kind %d", (INT) k );
04598 }
04599
04600 while (!val_idx && initv_stack.Elements() > 0) {
04601 val_idx = INITV_next(initv_stack.Pop());
04602 }
04603 }
04604 }
04605
04606
04607
04608 struct Localize_Nested_PU_Exception_Region {
04609 INITO_IDX old_inito;
04610 VAR_TABLE *vtab;
04611 SYMTAB_IDX level;
04612 Localize_Nested_PU_Exception_Region(INITO_IDX _old_inito, VAR_TABLE *_vtab,
04613 SYMTAB_IDX _level) : old_inito(_old_inito), vtab(_vtab), level(_level) { }
04614 BOOL operator() (UINT32 nested_raw_idx, const INITO *) const {
04615 INITO_IDX nested_inito_idx = make_INITO_IDX(nested_raw_idx, level);
04616
04617 if (old_inito == nested_inito_idx) {
04618 Localize_All_INITVKIND_SYMOFFs(old_inito, vtab);
04619 return TRUE;
04620 }
04621 return FALSE;
04622 }
04623 };
04624
04625
04626
04627
04628 static void
04629 Process_Exception_Region ( WN * node, VAR_TABLE * vtab )
04630 {
04631 char *localname;
04632 INITO_IDX old_inito, new_inito;
04633 ST *old_initst, *new_initst;
04634 INITV_IDX old_initv, new_initv, pinito, parent, prev;
04635 STACK<INITV_IDX> old_stack(Malloc_Mem_Pool), new_stack(Malloc_Mem_Pool);
04636
04637 Is_True(((WN_opcode(node) == OPC_REGION) && WN_ereg_supp(node)),
04638 ("expecting region node with ereg_supp"));
04639
04640 #ifdef Is_True_On
04641 switch (mpt) {
04642 case MPP_SINGLE:
04643 case MPP_PDO:
04644 case MPP_PARALLEL_DO:
04645 case MPP_PARALLEL_REGION:
04646 case MPP_ORPHAN:
04647 break;
04648 default:
04649 Fail_FmtAssertion("not inside a PARALLEL region");
04650 }
04651 #endif
04652
04653 #ifdef KEY
04654
04655 if (parallel_proc)
04656 #endif
04657 Set_PU_has_exc_scopes(Pu_Table[ST_pu(*parallel_proc)]);
04658
04659 old_inito = WN_ereg_supp(node);
04660
04661
04662
04663
04664
04665
04666
04667
04668 if (For_all_until(Inito_Table, Current_scope,
04669 Localize_Nested_PU_Exception_Region(old_inito, vtab,
04670 Current_scope)) != 0)
04671 return;
04672
04673 old_initst = INITO_st(old_inito);
04674 old_initv = INITO_val(old_inito);
04675
04676 localname = (char *) alloca(strlen(ST_name(old_initst)) + 32);
04677 sprintf ( localname, "__mpstatic_%s", ST_name(old_initst) );
04678
04679 new_initst = New_ST (CURRENT_SYMTAB);
04680 ST_Init (new_initst,
04681 Save_Str ( localname ),
04682 ST_class(old_initst),
04683 ST_sclass(old_initst),
04684 ST_export(old_initst),
04685 ST_type(old_initst));
04686
04687
04688 new_initst->flags = old_initst->flags;
04689 new_initst->flags_ext = old_initst->flags_ext;
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699 Set_ST_is_not_used(*old_initst);
04700
04701 WN_ereg_supp(node) = new_inito = New_INITO ( new_initst );
04702
04703 pinito = new_inito;
04704 parent = 0;
04705 prev = 0;
04706
04707 while ( old_initv ) {
04708
04709 (void) Initv_Table.New_entry(new_initv);
04710 INITV& new_initv_ref = Initv_Table[new_initv];
04711 INITV& old_initv_ref = Initv_Table[old_initv];
04712
04713 if (pinito) {
04714 Set_INITO_val(pinito, new_initv);
04715 pinito = 0;
04716 } else if (parent) {
04717 Set_INITV_blk(parent, new_initv);
04718 parent = 0;
04719 } else if (prev) {
04720 Set_INITV_next(prev, new_initv);
04721 }
04722
04723 INITVKIND k = INITV_kind(old_initv);
04724 switch ( k ) {
04725
04726 case INITVKIND_SYMOFF:
04727 INITV_Set_SYMOFF(new_initv_ref, INITV_repeat1(old_initv_ref),
04728 INITV_st(old_initv_ref), INITV_ofst(old_initv_ref));
04729 Localize_INITVKIND_SYMOFF(new_initv, old_initv, vtab);
04730 old_initv = INITV_next(old_initv);
04731 prev = new_initv;
04732 break;
04733
04734 case INITVKIND_ZERO:
04735 INITV_Set_ZERO(new_initv_ref, INITV_mtype(old_initv_ref),
04736 INITV_repeat2(old_initv_ref));
04737 old_initv = INITV_next(old_initv);
04738 prev = new_initv;
04739 break;
04740
04741 case INITVKIND_ONE:
04742 INITV_Set_ONE(new_initv_ref, INITV_mtype(old_initv_ref),
04743 INITV_repeat2(old_initv_ref));
04744 old_initv = INITV_next(old_initv);
04745 prev = new_initv;
04746 break;
04747
04748 case INITVKIND_VAL:
04749 INITV_Set_VAL(new_initv_ref, INITV_tc(old_initv_ref),
04750 INITV_repeat2(old_initv_ref));
04751 old_initv = INITV_next(old_initv);
04752 prev = new_initv;
04753 break;
04754
04755 case INITVKIND_BLOCK:
04756 INITV_Set_BLOCK(new_initv_ref, INITV_repeat1(old_initv_ref), 0);
04757 old_stack.Push(old_initv);
04758 new_stack.Push(new_initv);
04759 old_initv = INITV_blk(old_initv);
04760 parent = new_initv;
04761 prev = 0;
04762 break;
04763
04764 case INITVKIND_PAD:
04765 INITV_Set_PAD(new_initv_ref, INITV_pad(old_initv_ref));
04766 old_initv = INITV_next(old_initv);
04767 prev = new_initv;
04768 break;
04769
04770 case INITVKIND_SYMDIFF:
04771 case INITVKIND_SYMDIFF16:
04772 INITV_Set_SYMDIFF(new_initv_ref, INITV_repeat1(old_initv_ref),
04773 INITV_lab1(old_initv_ref), INITV_st2(old_initv_ref),
04774 INITV_kind(old_initv) == INITVKIND_SYMDIFF16);
04775 old_initv = INITV_next(old_initv);
04776 prev = new_initv;
04777 break;
04778
04779 case INITVKIND_LABEL:
04780 INITV_Set_LABEL(new_initv_ref, INITV_repeat1(old_initv_ref),
04781 Translate_Label(INITV_lab(old_initv_ref)));
04782 old_initv = INITV_next(old_initv);
04783 prev = new_initv;
04784 break;
04785
04786 default:
04787 Fail_FmtAssertion ( "unknown INITV kind %d", (INT) k );
04788
04789 }
04790
04791 while (!old_initv && old_stack.Elements() > 0) {
04792 old_initv = INITV_next(old_stack.Pop());
04793 prev = new_stack.Pop();
04794 }
04795
04796 }
04797
04798 }
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809 class Localize_Parent_Stack {
04810 public:
04811 BOOL orphaned;
04812 STACK<WN *> parent_stack;
04813
04814
04815 Localize_Parent_Stack(BOOL _orphaned, WN *top) : orphaned(_orphaned),
04816 parent_stack(Malloc_Mem_Pool) { Push(top); }
04817 void Push(WN *wn) { if (orphaned) parent_stack.Push(wn); }
04818 void Pop() { if (orphaned) (void) parent_stack.Pop(); }
04819 };
04820
04821
04822 #define OMP_NON_POD_LASTLOCAL_FLAG_NAME "__omp_non_pod_lastlocal"
04823 #define OMP_NON_POD_FIRST_AND_LASTLOCAL_FLAG_NAME \
04824 "__omp_non_pod_first_and_lastlocal"
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844 BOOL
04845 Is_Nonpod_Finalization_IF(WN *wn, BOOL *is_first_and_last)
04846 {
04847 if (WN_operator(wn) != OPR_IF)
04848 return FALSE;
04849
04850 WN *test = WN_if_test(wn);
04851 if (WN_operator(test) != OPR_NE)
04852 return FALSE;
04853
04854 WN *ldid = WN_kid0(test), *intconst = WN_kid1(test);
04855 ST *ldid_st;
04856 if (WN_operator(ldid) != OPR_LDID ||
04857 (ldid_st = WN_st(ldid)) == NULL)
04858 return FALSE;
04859
04860 BOOL first_and_last;
04861
04862 if (strcmp(ST_name(*ldid_st), OMP_NON_POD_LASTLOCAL_FLAG_NAME) == 0)
04863 first_and_last = FALSE;
04864 else if (strcmp(ST_name(*ldid_st),
04865 OMP_NON_POD_FIRST_AND_LASTLOCAL_FLAG_NAME) == 0)
04866 first_and_last = TRUE;
04867 else
04868 return FALSE;
04869
04870 if (WN_operator(intconst) != OPR_INTCONST ||
04871 WN_rtype(intconst) != MTYPE_I4 ||
04872 WN_const_val(intconst) != 0)
04873 return FALSE;
04874
04875 *is_first_and_last = first_and_last;
04876 return TRUE;
04877 }
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904 static WN *
04905 Walk_and_Localize (WN * tree, VAR_TABLE * vtab, Localize_Parent_Stack * lps,
04906 BOOL is_par_region, WN **non_pod_finalization)
04907 {
04908 OPCODE op;
04909 OPERATOR opr;
04910 INT32 i;
04911 WN *r;
04912 WN *temp;
04913 ST *old_sym;
04914 WN_OFFSET old_offset;
04915 VAR_TABLE *w;
04916 const BOOL is_orphaned_worksharing =
04917 (mpt == MPP_ORPHANED_PDO || mpt == MPP_ORPHANED_SINGLE);
04918
04919
04920
04921 if (tree == NULL)
04922 return (tree);
04923
04924
04925
04926 op = WN_opcode(tree);
04927 opr = OPCODE_operator(op);
04928
04929
04930
04931 if (opr == OPR_LDID) {
04932 old_sym = WN_st(tree);
04933 old_offset = WN_offsetx(tree);
04934 for (w=vtab; w->orig_st; w++) {
04935 if ((w->orig_st == old_sym) &&
04936 #ifndef KEY
04937 (w->has_offset ? (w->orig_offset == old_offset) : TRUE ) &&
04938 #endif
04939 (w->vtype != VAR_REDUCTION_ARRAY) &&
04940 ! (w->is_non_pod && is_orphaned_worksharing)) {
04941 if (w->is_static_array) {
04942 temp = WN_Lda ( Pointer_type, w->new_offset, w->new_st);
04943
04944
04945 Set_BE_ST_pu_needs_addr_flag_adjust (PU_Info_proc_sym(Current_PU_Info));
04946 WN_Delete ( tree );
04947 tree = temp;
04948
04949
04950
04951
04952
04953 op = WN_opcode(tree);
04954 opr = OPCODE_operator(op);
04955 } else {
04956 WN_st_idx(tree) = ST_st_idx(w->new_st);
04957 if (w->has_offset)
04958 #ifdef KEY
04959 WN_set_offsetx(tree, old_offset);
04960 #else
04961 WN_set_offsetx(tree, w->new_offset);
04962 #endif
04963 }
04964 if (w->is_dynamic_array) {
04965
04966 WN *ldst, *ldst_child = tree;
04967
04968
04969 for (INT i = 0; i < lps->parent_stack.Elements();
04970 i++, ldst_child = ldst) {
04971 ldst = lps->parent_stack.Top_nth(i);
04972 opr = WN_operator(ldst);
04973
04974
04975
04976 if (opr == OPR_ARRAY && ldst_child != WN_kid0(ldst))
04977 break;
04978
04979
04980 if (opr == OPR_ISTORE && ldst_child != WN_kid1(ldst))
04981 break;
04982
04983 if (opr != OPR_ILOAD && opr != OPR_ISTORE)
04984 continue;
04985
04986
04987
04988
04989 Erase_Restricted_Mapping(ldst);
04990 }
04991 }
04992 break;
04993 }
04994 }
04995 } else if (opr == OPR_STID) {
04996 old_sym = WN_st(tree);
04997 old_offset = WN_offsetx(tree);
04998 for (w=vtab; w->orig_st; w++) {
04999 if ((w->vtree == NULL) &&
05000 (w->orig_st == old_sym) &&
05001 #ifndef KEY
05002 (w->has_offset ? (w->orig_offset == old_offset) : TRUE ) &&
05003 #endif
05004 ! (w->is_non_pod && is_orphaned_worksharing)) {
05005 WN_st_idx(tree) = ST_st_idx(w->new_st);
05006 if (w->has_offset)
05007 #ifdef KEY
05008 WN_set_offsetx(tree, old_offset);
05009 #else
05010 WN_set_offsetx(tree, w->new_offset);
05011 #endif
05012 break;
05013 }
05014 }
05015 } else if (opr == OPR_ILOAD) {
05016 for (w=vtab; w->orig_st; w++) {
05017 if ((w->vtree && (WN_Compare_Trees(w->vtree, WN_kid0(tree)) == 0)) ||
05018 (w->vtreex && (WN_Compare_Trees(w->vtreex, WN_kid0(tree)) == 0))) {
05019 Is_True(! w->is_non_pod, ("non-POD pointer expression?!?"));
05020 temp = WN_RLdid ( Promote_Type(w->mtype), w->mtype, w->new_offset,
05021 w->new_st, w->ty );
05022 #ifdef KEY // bug 10707: honor the type in the original tree node
05023 if (WN_rtype(tree) == MTYPE_F8 && WN_rtype(temp) == MTYPE_C8 ||
05024 WN_rtype(tree) == MTYPE_F4 && WN_rtype(temp) == MTYPE_C4) {
05025 WN_set_rtype(temp, WN_rtype(tree));
05026 WN_set_desc(temp, WN_desc(tree));
05027 }
05028 #endif
05029 WN_DELETE_Tree ( tree );
05030 tree = temp;
05031 op = WN_opcode(tree);
05032 opr = OPCODE_operator(op);
05033 break;
05034 }
05035 }
05036 #ifdef KEY
05037 if (opr == OPR_ILOAD)
05038 WN_kid0(tree) = Walk_and_Localize ( WN_kid0(tree), vtab, lps,
05039 is_par_region, non_pod_finalization );
05040 #endif // KEY
05041 } else if (opr == OPR_ISTORE) {
05042 for (w=vtab; w->orig_st; w++) {
05043 if ((w->vtree && (WN_Compare_Trees(w->vtree, WN_kid1(tree)) == 0)) ||
05044 (w->vtreex && (WN_Compare_Trees(w->vtreex, WN_kid1(tree)) == 0))) {
05045 Is_True(! w->is_non_pod, ("non-POD pointer expression?!?"));
05046 temp = WN_Stid ( w->mtype, w->new_offset, w->new_st, w->ty,
05047 WN_kid0(tree) );
05048 #ifdef KEY // bug 10707: honor the type in the original tree node
05049 if (WN_desc(tree) == MTYPE_F8 && WN_desc(temp) == MTYPE_C8 ||
05050 WN_desc(tree) == MTYPE_F4 && WN_desc(temp) == MTYPE_C4) {
05051 WN_set_desc(temp, WN_desc(tree));
05052 }
05053 #endif
05054 WN_linenum(temp) = WN_linenum(tree);
05055 WN_prev(temp) = WN_prev(tree);
05056 if (WN_prev(temp))
05057 WN_next(WN_prev(temp)) = temp;
05058 WN_next(temp) = WN_next(tree);
05059 if (WN_next(temp))
05060 WN_prev(WN_next(temp)) = temp;
05061 WN_DELETE_Tree ( WN_kid1(tree) );
05062 WN_Delete ( tree );
05063 tree = temp;
05064 op = WN_opcode(tree);
05065 opr = OPCODE_operator(op);
05066 break;
05067 }
05068 }
05069
05070
05071 } else if ((op == OPC_REGION) && WN_ereg_supp(tree) &&
05072 !is_orphaned_worksharing) {
05073 Process_Exception_Region ( tree, vtab );
05074 } else if (OPCODE_has_label(op) && is_par_region &&
05075 !is_orphaned_worksharing) {
05076 LABEL_IDX new_lab = Translate_Label (WN_label_number(tree));
05077 WN_label_number(tree) = new_lab;
05078 if (opr == OPR_LDA_LABEL) Set_LABEL_addr_saved(new_lab);
05079 } else if (OPCODE_has_sym(op) && WN_st(tree)) {
05080 old_sym = WN_st(tree);
05081 old_offset = OPCODE_has_offset(op) ? WN_offsetx(tree) : 0;
05082 for (w=vtab; w->orig_st; w++) {
05083 if ((w->vtype != VAR_REDUCTION_ARRAY) &&
05084 (w->orig_st == old_sym) &&
05085 (w->has_offset ? (w->orig_offset == old_offset) : TRUE ) &&
05086 ! (w->is_non_pod && is_orphaned_worksharing)) {
05087 WN_st_idx(tree) = ST_st_idx(w->new_st);
05088 if (OPCODE_has_offset(op) && w->has_offset)
05089 WN_set_offsetx(tree, w->new_offset);
05090 break;
05091 }
05092 }
05093 }
05094
05095
05096
05097 lps->Push(tree);
05098 if (op == OPC_BLOCK) {
05099 r = WN_first(tree);
05100 while (r) {
05101 r = Walk_and_Localize ( r, vtab, lps, is_par_region,
05102 non_pod_finalization );
05103 if (WN_prev(r) == NULL)
05104 WN_first(tree) = r;
05105 if (WN_next(r) == NULL)
05106 WN_last(tree) = r;
05107
05108 if (Is_Nonpod_Finalization_IF(r, &non_pod_first_and_lastprivate)) {
05109 if (*non_pod_finalization)
05110 Fail_FmtAssertion("already found non-POD finalization IF");
05111
05112 WN *bar1 = WN_prev(r), *bar2 = WN_next(r), *then = WN_then(r),
05113 *bar3 = WN_first(then), *bar4 = WN_last(then);
05114 Is_True(bar1 && WN_operator(bar1) == OPR_FORWARD_BARRIER,
05115 ("bad bar1"));
05116 Is_True(bar2 && WN_operator(bar2) == OPR_BACKWARD_BARRIER,
05117 ("bad bar2"));
05118 Is_True(bar3 && WN_operator(bar3) == OPR_BACKWARD_BARRIER,
05119 ("bad bar3"));
05120 Is_True(bar4 && WN_operator(bar4) == OPR_FORWARD_BARRIER,
05121 ("bad bar4"));
05122 WN_DELETE_FromBlock(tree, bar1);
05123 WN_DELETE_FromBlock(tree, bar2);
05124 WN_DELETE_FromBlock(then, bar3);
05125 WN_DELETE_FromBlock(then, bar4);
05126
05127 *non_pod_finalization = r;
05128 WN *tmp = WN_next(r);
05129 WN_EXTRACT_FromBlock(tree, r);
05130 r = tmp;
05131 } else {
05132 r = WN_next(r);
05133 }
05134 }
05135 } else {
05136 for (i=0; i < WN_kid_count(tree); i++)
05137 WN_kid(tree, i) = Walk_and_Localize ( WN_kid(tree, i), vtab, lps,
05138 is_par_region,
05139 non_pod_finalization );
05140 }
05141 lps->Pop();
05142
05143 return (tree);
05144 }
05145
05146
05147
05148
05149
05150
05151
05152
05153 static void
05154 Make_Local_Temps ( void )
05155 {
05156
05157
05158
05159
05160 Create_Preg_or_Temp( do_index_type, "temp_limit", &limit_st, &limit_ofst );
05161
05162 Create_Temp( do_index_type, "do_upper", &local_upper );
05163 Set_ST_addr_passed( local_upper );
05164
05165 Create_Temp( do_index_type, "do_lower", &local_lower );
05166 Set_ST_addr_passed( local_lower );
05167
05168 Create_Temp( do_index_type, "do_stride", &local_stride );
05169 Set_ST_addr_passed( local_stride );
05170
05171 Create_Temp( MTYPE_I4, "last_iter", &last_iter );
05172 Set_ST_addr_passed( last_iter );
05173
05174 }
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187 static TY_IDX
05188 Lock_Padding_TY ()
05189 {
05190
05191 static TY_IDX arr_ty = TY_IDX_ZERO;
05192
05193 if (arr_ty == TY_IDX_ZERO)
05194 {
05195
05196 TY& ty = New_TY (arr_ty);
05197 TY_Init (ty, 128, KIND_ARRAY, MTYPE_UNKNOWN, Save_Str("__lock_pad_type"));
05198 Set_TY_etype(ty, Be_Type_Tbl(MTYPE_I1));
05199
05200 ARB_HANDLE arb = New_ARB ();
05201 ARB_Init (arb, 1, 1, 1);
05202 Set_ARB_dimension(arb, 1);
05203 Set_ARB_first_dimen(arb);
05204 Set_ARB_last_dimen(arb);
05205 Set_ARB_const_lbnd(arb);
05206 Set_ARB_lbnd_val(arb,0);
05207 Set_ARB_const_ubnd(arb);
05208 Set_ARB_ubnd_val(arb,128-1);
05209 Set_ARB_const_stride(arb);
05210 Set_ARB_stride_val(arb,1);
05211
05212 Set_TY_arb(ty, arb);
05213 Set_TY_align (arr_ty, 128);
05214 }
05215
05216 return arr_ty;
05217 }
05218
05219
05220
05221 static ST *
05222 Create_Critical_Lock ( void )
05223 {
05224 ST *st;
05225 char st_name[32];
05226
05227 st = New_ST (GLOBAL_SYMTAB);
05228 sprintf ( st_name, "__mplock_%d", ++lock_id );
05229 Create_Lock_Type( );
05230 ST_Init (st,
05231 Save_Str (st_name),
05232 CLASS_VAR,
05233 SCLASS_COMMON,
05234 EXPORT_PREEMPTIBLE,
05235 lock_ty_idx );
05236
05237 Set_ST_addr_passed(st);
05238
05239 shared_table[shared_count++] = st;
05240
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261 critical_lock_not_init = TRUE;
05262
05263 return (st);
05264 }
05265
05266
05267
05268 static ST *
05269 Create_Unnamed_Critical_Lock ( void )
05270 {
05271 if( unnamed_lock_st != NULL )
05272 {
05273 critical_lock_not_init = FALSE;
05274 return unnamed_lock_st;
05275 }
05276 ST *st;
05277 char st_name[32];
05278
05279 st = New_ST (GLOBAL_SYMTAB);
05280
05281 sprintf ( st_name, "__mplock_0" );
05282 Create_Lock_Type( );
05283 ST_Init (st,
05284 Save_Str (st_name),
05285 CLASS_VAR,
05286 SCLASS_COMMON,
05287 EXPORT_PREEMPTIBLE,
05288 lock_ty_idx );
05289
05290 Set_ST_addr_passed(st);
05291
05292
05293
05294 shared_table[shared_count++] = st;
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311
05312
05313
05314
05315 critical_lock_not_init = TRUE;
05316 unnamed_lock_st = st;
05317
05318 return (st);
05319 }
05320
05321
05322
05323
05324
05325 static ST * Create_Name_Lock (ST* lock_name)
05326 {
05327 ST *st;
05328
05329 char *name;
05330
05331 name = (char*) alloca (Targ_String_Length(ST_tcon_val(lock_name)) + 30);
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362 Create_Lock_Type( );
05363 sprintf (name, "__namelock_%s",
05364 Targ_String_Address(ST_tcon_val(lock_name)));
05365 st = New_ST (GLOBAL_SYMTAB);
05366 ST_Init(st,
05367 Save_Str(name),
05368 CLASS_VAR,
05369 SCLASS_COMMON,
05370 EXPORT_PREEMPTIBLE,
05371 lock_ty_idx );
05372 Set_ST_addr_passed(st);
05373
05374 critical_lock_not_init = TRUE;
05375
05376 return (st);
05377 }
05378
05379
05380
05381
05382
05383 static void
05384 Process_Preg_Temps ( WN * tree, BOOL is_region )
05385 {
05386 INT32 i;
05387 INT32 tcnt = PREG_Table_Size(CURRENT_SYMTAB);
05388 BOOL anytemp = FALSE;
05389 ST *st;
05390 TY_IDX ty;
05391 WN *wn;
05392 TYPE_ID mtype;
05393 PREG_INFO *preg;
05394 PREG_CLASS pclass;
05395 char tempname[32];
05396
05397 if (tcnt == 0)
05398 return;
05399
05400 PREG_INFO_TABLE prit(&mp_lower_pool, tcnt, TRUE, &preg_info_table);
05401
05402
05403
05404
05405 Walk_and_Info_Pregs ( tree );
05406
05407 for (wn = reduction_nodes; wn; wn = WN_next(wn))
05408 if ((WN_opcode(wn) == OPC_PRAGMA) && WN_st(wn) &&
05409 (ST_class(WN_st(wn)) == CLASS_PREG) &&
05410 !Preg_Is_Dedicated(WN_offsetx(wn)) )
05411 prit[Get_Preg_Idx(WN_offsetx(wn))].reduction_list = TRUE;
05412
05413 for (wn = lastlocal_nodes; wn; wn = WN_next(wn))
05414 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05415 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05416 prit[Get_Preg_Idx(WN_offsetx(wn))].lastlocal_list = TRUE;
05417 prit[Get_Preg_Idx(WN_offsetx(wn))].shared_flags = WN_pragma_arg2(wn);
05418 }
05419
05420 for (wn = local_nodes; wn; wn = WN_next(wn))
05421 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05422 !Preg_Is_Dedicated(WN_offsetx(wn)) )
05423 prit[Get_Preg_Idx(WN_offsetx(wn))].local_list = TRUE;
05424
05425 for (wn = firstprivate_nodes; wn; wn = WN_next(wn))
05426 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05427 !Preg_Is_Dedicated(WN_offsetx(wn)) )
05428
05429 prit[Get_Preg_Idx(WN_offsetx(wn))].local_list = TRUE;
05430
05431 for (wn = shared_nodes; wn; wn = WN_next(wn))
05432 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05433 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05434 prit[Get_Preg_Idx(WN_offsetx(wn))].shared_list = TRUE;
05435 prit[Get_Preg_Idx(WN_offsetx(wn))].shared_flags = WN_pragma_arg2(wn);
05436 }
05437
05438 if (if_preamble_block)
05439 for (wn = WN_first(if_preamble_block); wn; wn = WN_next(wn))
05440 if ((WN_operator(wn) == OPR_STID) &&
05441 (ST_class(WN_st(wn)) == CLASS_PREG) &&
05442 !Preg_Is_Dedicated(WN_offsetx(wn)) )
05443 prit[Get_Preg_Idx(WN_offsetx(wn))].preamble_store = TRUE;
05444
05445 if (do_preamble_block)
05446 for (wn = WN_first(do_preamble_block); wn; wn = WN_next(wn))
05447 if ((WN_operator(wn) == OPR_STID) &&
05448 (ST_class(WN_st(wn)) == CLASS_PREG) &&
05449 !Preg_Is_Dedicated(WN_offsetx(wn)) )
05450 prit[Get_Preg_Idx(WN_offsetx(wn))].preamble_store = TRUE;
05451
05452
05453
05454
05455 for (i = 1; i < tcnt; i++) {
05456 preg = &prit[i];
05457
05458 if (preg->type == MTYPE_UNKNOWN)
05459 pclass = PCLASS_DEADIN_DEADOUT;
05460 else if (preg->lastlocal_list)
05461 if (preg->shared_flags & SHARED_DEADOUT)
05462 pclass = PCLASS_DEADIN_DEADOUT;
05463 else
05464 pclass = PCLASS_DEADIN_LIVEOUT;
05465 else if (preg->local_list)
05466 if (preg->preamble_store)
05467 pclass = PCLASS_COPYIN_DEADOUT;
05468 else
05469 pclass = PCLASS_DEADIN_DEADOUT;
05470 else if (preg->reduction_list)
05471 pclass = PCLASS_LIVEIN_LIVEOUT;
05472 else if (preg->shared_list)
05473 if (preg->shared_flags & SHARED_DEADIN)
05474 if (preg->shared_flags & SHARED_DEADOUT)
05475 pclass = PCLASS_DEADIN_DEADOUT;
05476 else
05477 pclass = PCLASS_DEADIN_LIVEOUT;
05478 else
05479 if (preg->shared_flags & SHARED_DEADOUT)
05480 pclass = PCLASS_LIVEIN_DEADOUT;
05481 else
05482 pclass = PCLASS_LIVEIN_LIVEOUT;
05483 else if (preg->preamble_store)
05484 pclass = PCLASS_COPYIN_DEADOUT;
05485 else
05486 pclass = PCLASS_DEADIN_DEADOUT;
05487 preg->pclass = pclass;
05488
05489 if (pclass != PCLASS_DEADIN_DEADOUT) {
05490
05491 anytemp = TRUE;
05492 PREG_NUM pnum = Get_Preg_Num(i);
05493 mtype = preg->type;
05494 ty = MTYPE_To_TY ( mtype );
05495 sprintf ( tempname, "__mptemp_preg%d", pnum );
05496
05497 st = New_ST ( );
05498 ST_Init ( st, Save_Str ( tempname ), CLASS_VAR, SCLASS_AUTO,
05499 EXPORT_LOCAL, ty );
05500
05501 Set_ST_has_nested_ref ( st );
05502
05503 preg->temp = st;
05504
05505
05506 if ((pclass == PCLASS_COPYIN_DEADOUT) ||
05507 (pclass == PCLASS_COPYIN_COPYOUT) ||
05508 (pclass == PCLASS_LIVEIN_DEADOUT) ||
05509 (pclass == PCLASS_LIVEIN_LIVEOUT)) {
05510 wn = WN_Stid ( mtype, 0, st, ty, WN_LdidPreg ( mtype, pnum ));
05511 WN_linenum(wn) = line_number;
05512 if (livein_block == NULL)
05513 livein_block = WN_CreateBlock ( );
05514 WN_INSERT_BlockLast ( livein_block, wn );
05515 }
05516
05517
05518 if ((pclass == PCLASS_COPYIN_DEADOUT) ||
05519 (pclass == PCLASS_COPYIN_COPYOUT)) {
05520 wn = WN_StidIntoPreg ( mtype, pnum, MTYPE_To_PREG ( mtype ),
05521 WN_RLdid ( Promote_Type(mtype), mtype, 0, st,
05522 ty ));
05523 WN_linenum(wn) = line_number;
05524 if (copyin_block == NULL)
05525 copyin_block = WN_CreateBlock ( );
05526 WN_INSERT_BlockLast ( copyin_block, wn );
05527 }
05528
05529
05530 if ((pclass == PCLASS_DEADIN_COPYOUT) ||
05531 (pclass == PCLASS_COPYIN_COPYOUT)) {
05532 wn = WN_Stid ( mtype, 0, st, ty, WN_LdidPreg ( mtype, pnum ));
05533 WN_linenum(wn) = line_number;
05534 if (copyout_block == NULL)
05535 copyout_block = WN_CreateBlock ( );
05536 WN_INSERT_BlockLast ( copyout_block, wn );
05537 }
05538
05539
05540 if ((pclass == PCLASS_DEADIN_COPYOUT) ||
05541 (pclass == PCLASS_COPYIN_COPYOUT) ||
05542 (pclass == PCLASS_DEADIN_LIVEOUT) ||
05543 (pclass == PCLASS_LIVEIN_LIVEOUT)) {
05544 wn = WN_StidIntoPreg ( mtype, pnum, MTYPE_To_PREG ( mtype ),
05545 WN_RLdid ( Promote_Type(mtype), mtype, 0, st,
05546 ty ));
05547 WN_linenum(wn) = line_number;
05548 if (liveout_block == NULL)
05549 liveout_block = WN_CreateBlock ( );
05550 WN_INSERT_BlockLast ( liveout_block, wn );
05551 shared_table[shared_count++] = st;
05552 }
05553
05554 }
05555 }
05556
05557
05558
05559 if (anytemp) {
05560
05561 Walk_and_Replace_Pregs ( tree );
05562
05563 for (wn = reduction_nodes; wn; wn = WN_next(wn))
05564 if ((WN_opcode(wn) == OPC_PRAGMA) && WN_st(wn) &&
05565 (ST_class(WN_st(wn)) == CLASS_PREG) &&
05566 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05567 PREG_NUM pnum = Get_Preg_Idx(WN_offsetx(wn));
05568 preg = &prit[pnum];
05569 if (preg->temp) {
05570 WN_st_idx(wn) = ST_st_idx(preg->temp);
05571 WN_set_offsetx(wn, 0);
05572 }
05573 } else if (WN_opcode(wn) == OPC_XPRAGMA)
05574 Walk_and_Replace_Pregs ( WN_kid0(wn) );
05575
05576 for (wn = lastlocal_nodes; wn; wn = WN_next(wn))
05577 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05578 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05579 PREG_NUM pnum = Get_Preg_Idx(WN_offsetx(wn));
05580 preg = &prit[pnum];
05581 if (preg->temp) {
05582 WN_st_idx(wn) = ST_st_idx(preg->temp);
05583 WN_set_offsetx(wn, 0);
05584 }
05585 }
05586
05587 for (wn = local_nodes; wn; wn = WN_next(wn))
05588 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05589 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05590 PREG_NUM pnum = Get_Preg_Idx(WN_offsetx(wn));
05591 preg = &prit[pnum];
05592 if (preg->temp) {
05593 WN_st_idx(wn) = ST_st_idx(preg->temp);
05594 WN_set_offsetx(wn, 0);
05595 }
05596 }
05597
05598 for (wn = firstprivate_nodes; wn; wn = WN_next(wn))
05599 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05600 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05601 PREG_NUM pnum = Get_Preg_Idx(WN_offsetx(wn));
05602 preg = &prit[pnum];
05603 if (preg->temp) {
05604 WN_st_idx(wn) = ST_st_idx(preg->temp);
05605 WN_set_offsetx(wn, 0);
05606 }
05607 }
05608
05609 for (wn = shared_nodes; wn; wn = WN_next(wn))
05610 if (WN_st(wn) && (ST_class(WN_st(wn)) == CLASS_PREG) &&
05611 !Preg_Is_Dedicated(WN_offsetx(wn)) ) {
05612 PREG_NUM pnum = Get_Preg_Idx(WN_offsetx(wn));
05613 preg = &prit[pnum];
05614 if (preg->temp) {
05615 WN_st_idx(wn) = ST_st_idx(preg->temp);
05616 WN_set_offsetx(wn, 0);
05617 }
05618 }
05619
05620 }
05621 }
05622
05623
05624
05625
05626
05627
05628
05629 static void
05630 Transfer_Maps_R ( WN_MAP_TAB * parent, WN_MAP_TAB * child, WN * tree,
05631 RID * root_rid );
05632
05633 static void
05634 Transfer_Maps ( WN_MAP_TAB * parent, WN_MAP_TAB * child, WN * tree,
05635 RID * root_rid )
05636 {
05637
05638
05639 HASH_TABLE<WN *, INT32> fb_map(NUM_HASH_ELEMENTS, Malloc_Mem_Pool);
05640 WN_ITER *wni = WN_WALK_TreeIter(tree);
05641
05642 for ( ; wni; wni = WN_WALK_TreeNext(wni)) {
05643 WN *wn = WN_ITER_wn(wni);
05644
05645 fb_map.Enter(wn, IPA_WN_MAP32_Get(child, WN_MAP_FEEDBACK, wn));
05646 }
05647
05648 Transfer_Maps_R(parent, child, tree, root_rid);
05649
05650
05651 HASH_TABLE_ITER<WN *, INT32> fb_map_iter(&fb_map);
05652 WN *wn;
05653 INT32 val;
05654
05655 while (fb_map_iter.Step(&wn, &val))
05656 IPA_WN_MAP32_Set(child, WN_MAP_FEEDBACK, wn, val);
05657
05658
05659 }
05660
05661
05662 static void
05663 Transfer_Maps_R ( WN_MAP_TAB * parent, WN_MAP_TAB * child, WN * tree,
05664 RID * root_rid )
05665 {
05666 WN *node;
05667 INT32 i;
05668
05669 if (tree) {
05670 if (WN_opcode(tree) == OPC_BLOCK) {
05671 for (node = WN_first(tree); node; node = WN_next(node))
05672 Transfer_Maps_R ( parent, child, node, root_rid );
05673 } else
05674 for (i = 0; i < WN_kid_count(tree); i++)
05675 Transfer_Maps_R ( parent, child, WN_kid(tree, i), root_rid );
05676
05677 if (WN_map_id(tree) != -1) {
05678 RID *rid = REGION_get_rid ( tree );
05679 IPA_WN_Move_Maps_PU ( parent, child, tree );
05680 if (WN_opcode(tree) == OPC_REGION) {
05681 Is_True(root_rid != NULL, ("Transfer_Maps_R, NULL root RID"));
05682 RID_unlink ( rid );
05683 RID_Add_kid ( rid, root_rid );
05684 }
05685 }
05686 }
05687 }
05688
05689
05690 ST_IDX Make_MPRuntime_ST ( MPRUNTIME rop )
05691 {
05692 Is_True(rop >= MPRUNTIME_FIRST && rop <= MPRUNTIME_LAST,
05693 ("Make_MPRuntime_ST: bad rop == %d", (INT) rop));
05694
05695
05696 if (mpruntime_ty == TY_IDX_ZERO) {
05697 TY &mpr_ty = New_TY ( mpruntime_ty );
05698 TY_Init(mpr_ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN,
05699 Save_Str(".mpruntime"));
05700 Set_TY_align(mpruntime_ty, 1);
05701
05702 TYLIST_IDX parm_idx;
05703 TYLIST& parm_list = New_TYLIST(parm_idx);
05704 Set_TY_tylist(mpr_ty, parm_idx);
05705 Set_TYLIST_type(parm_list, Be_Type_Tbl(MTYPE_I4));
05706
05707 Set_TYLIST_type(New_TYLIST(parm_idx), TY_IDX_ZERO);
05708
05709 TY_IDX ty_idx;
05710 TY &ty = New_TY ( ty_idx );
05711 TY_Init(ty, Pointer_Size, KIND_POINTER, Pointer_Mtype,
05712 Save_Str ( ".mpruntime_ptr" ));
05713 Set_TY_pointed(ty, mpruntime_ty);
05714
05715 Set_TY_align(ty_idx, Pointer_Size);
05716
05717 }
05718
05719 PU_IDX pu_idx;
05720 PU& pu = New_PU(pu_idx);
05721 PU_Init(pu, mpruntime_ty, CURRENT_SYMTAB);
05722
05723
05724
05725
05726 ST *st = New_ST ( GLOBAL_SYMTAB );
05727 ST_Init(st, Save_Str ( mpr_names[rop] ), CLASS_FUNC, SCLASS_EXTERN,
05728 EXPORT_PREEMPTIBLE, pu_idx);
05729
05730 Allocate_Object ( st );
05731
05732 mpr_sts[rop] = ST_st_idx(*st);
05733 return mpr_sts[rop];
05734 }
05735
05736
05737
05738
05739 static WN *
05740 Gen_MP_Load ( ST * st, WN_OFFSET offset, BOOL scalar_only )
05741 {
05742 WN *wn;
05743 TY_IDX ty = ST_type(st);
05744 #ifdef KEY // bug 7259
05745 if (scalar_only && TY_kind(ty) == KIND_STRUCT)
05746 ty = FLD_type(TY_fld(ty));
05747 #endif
05748 #ifdef KEY // bug 10681
05749 if (scalar_only && TY_kind(ty) == KIND_ARRAY)
05750 ty = TY_etype(ty);
05751 #endif
05752
05753 wn = WN_RLdid ( Promote_Type(TY_mtype(ty)),
05754 TY_mtype(ty), offset, st, ty );
05755
05756 return (wn);
05757 }
05758
05759
05760
05761
05762 static WN *
05763 Gen_MP_Store ( ST * st, WN_OFFSET offset, WN * value, BOOL scalar_only)
05764 {
05765 WN *wn;
05766 TY_IDX ty = ST_type(st);
05767 #ifdef KEY // bug 7259
05768 if (scalar_only && TY_kind(ty) == KIND_STRUCT)
05769 ty = FLD_type(TY_fld(ty));
05770 #endif
05771 #ifdef KEY // bug 10681
05772 if (scalar_only && TY_kind(ty) == KIND_ARRAY)
05773 ty = TY_etype(ty);
05774 #endif
05775
05776 wn = WN_Stid ( TY_mtype(ty), offset, st, ty, value );
05777 WN_linenum(wn) = line_number;
05778
05779 return (wn);
05780 }
05781
05782
05783
05784
05785 static WN *
05786 Gen_MP_Load_Store ( ST * from_st, WN_OFFSET from_offset,
05787 ST * to_st, WN_OFFSET to_offset,
05788 BOOL is_dynamic )
05789 {
05790 TY_IDX ty;
05791 TY_IDX pty;
05792 WN *wn;
05793 WN *laddr_wn;
05794 WN *saddr_wn;
05795 WN *bytes_wn;
05796 BOOL is_from_ptr;
05797 BOOL is_to_ptr;
05798
05799 is_from_ptr = (TY_kind(ST_type(from_st)) == KIND_POINTER);
05800 is_to_ptr = (TY_kind(ST_type(to_st)) == KIND_POINTER);
05801 if (is_from_ptr && is_to_ptr && !is_dynamic)
05802 is_from_ptr = is_to_ptr = FALSE;
05803
05804 ty = (is_from_ptr) ? TY_pointed(ST_type(from_st)) : ST_type(from_st);
05805
05806 #ifndef KEY
05807 if ((TY_kind(ty) != KIND_ARRAY) && (TY_kind(ty) != KIND_STRUCT))
05808 #else
05809 if (((TY_kind(ty) != KIND_ARRAY) && (TY_kind(ty) != KIND_STRUCT)) ||
05810
05811 TY_kind(ty) == KIND_STRUCT && TY_size(ty) == 0)
05812 #endif
05813 wn = Gen_MP_Store ( to_st, to_offset,
05814 Gen_MP_Load ( from_st, from_offset ));
05815 else {
05816 if (TY_size(ty) > INT32_MAX)
05817 bytes_wn = WN_Intconst ( MTYPE_I8, TY_size(ty) );
05818 else if (TY_size(ty) > 0)
05819 bytes_wn = WN_Intconst ( MTYPE_I4, TY_size(ty) );
05820 else
05821 bytes_wn = Calculate_Array_Size ( from_st, ty );
05822 if (is_from_ptr)
05823 laddr_wn = WN_RLdid ( Promote_Type(Pointer_type), Pointer_type,
05824 from_offset, from_st, ST_type(from_st) );
05825 else
05826 laddr_wn = WN_Lda ( Pointer_type, from_offset, from_st );
05827 if (is_to_ptr)
05828 saddr_wn = WN_RLdid ( Promote_Type(Pointer_type), Pointer_type,
05829 to_offset, to_st, ST_type(to_st) );
05830 else
05831 saddr_wn = WN_Lda ( Pointer_type, to_offset, to_st );
05832 pty = Make_Pointer_Type ( ty, FALSE );
05833 wn = WN_CreateMstore ( 0, pty,
05834 WN_CreateMload ( 0, pty, laddr_wn,
05835 WN_COPY_Tree (bytes_wn) ),
05836 saddr_wn, bytes_wn );
05837 }
05838
05839 return (wn);
05840 }
05841
05842
05843
05844
05845
05846 static WN *
05847 Gen_Barrier (ST* gtid)
05848 {
05849 WN *wn;
05850
05851 wn = WN_Create ( OPC_VCALL, 0 );
05852 WN_st_idx(wn) = GET_MPRUNTIME_ST ( MPR_OMP_BARRIER );
05853 WN_Set_Call_Non_Data_Mod ( wn );
05854 WN_Set_Call_Non_Data_Ref ( wn );
05855 WN_Set_Call_Non_Parm_Mod ( wn );
05856 WN_Set_Call_Non_Parm_Ref ( wn );
05857 WN_Set_Call_Parm_Ref ( wn );
05858 WN_linenum(wn) = line_number;
05859
05860 return (wn);
05861 }
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872 static BOOL
05873 is_omp_non_pod_copyin(WN *copyin_wn)
05874 {
05875 if (WN_opcode(copyin_wn) != OPC_XPRAGMA ||
05876 !WN_pragma_omp(copyin_wn))
05877 return FALSE;
05878
05879 WN *kid = WN_kid0(copyin_wn);
05880 if (!kid)
05881 return FALSE;
05882
05883 ST *st = WN_st(kid);
05884 if (!st)
05885 return FALSE;
05886
05887 return (ST_sym_class(st) == CLASS_FUNC);
05888 }
05889
05890 #ifdef KEY
05891 extern ST *ST_Source_COMMON_Block(ST *st, ST **split, BOOL want_st);
05892 extern ST *ST_Source_Block(ST *, ST **);
05893
05894 static ST*
05895 Get_Threadprv_St(WN *prags, ST *copyin_st, ST **copyin_local_st)
05896 {
05897 ST *split_block;
05898 ST *copyin_global_st = NULL;
05899 ST *common_block = ST_Source_Block(copyin_st, &split_block);
05900 if (!ST_is_thread_private(copyin_st) &&
05901 !(split_block && ST_is_thread_private(split_block)) &&
05902 !(common_block && ST_is_thread_private(common_block)))
05903 ErrMsg (EC_MPLOWER_copyin_st, copyin_st);
05904 BOOL match = FALSE;
05905 prags = WN_first(prags);
05906
05907 while (prags) {
05908 if (WN_opcode(prags) == OPC_PRAGMA &&
05909 WN_pragma(prags) == WN_PRAGMA_THREADPRIVATE &&
05910 WN_st(prags) == common_block) {
05911 *copyin_local_st = ST_ptr(WN_pragma_arg1(prags));
05912 copyin_global_st = ST_ptr(WN_pragma_arg2(prags));
05913 match = TRUE;
05914 }
05915 prags = WN_next(prags);
05916 }
05917 if (!match)
05918 Fail_FmtAssertion ( "bad copyin st (%s) in MP processing",
05919 ST_st_idx(copyin_st) );
05920 if (copyin_global_st)
05921 common_block = copyin_global_st;
05922 else
05923 Is_True (FALSE, ("Copyin source ST not found in MP processing"));
05924
05925 return common_block;
05926 }
05927
05928
05929
05930
05931
05932 void
05933 Post_MP_Processing (WN * pu)
05934 {
05935 Is_True (WN_operator (pu) == OPR_FUNC_ENTRY,
05936 ("Post_MP_Processing: Function entry node expected"));
05937
05938 local_nodes = NULL;
05939 local_count = 0;
05940
05941 WN * prags = WN_func_pragmas (pu);
05942 WN * body = WN_func_body (pu);
05943
05944 reference_block = WN_CreateBlock ( );
05945 WN *thread_priv_prag = WN_first(prags);
05946 while (thread_priv_prag) {
05947 if (WN_opcode(thread_priv_prag) == OPC_PRAGMA &&
05948 WN_pragma(thread_priv_prag) == WN_PRAGMA_THREADPRIVATE) {
05949 WN_INSERT_BlockLast ( reference_block,
05950 WN_CreatePragma ( WN_PRAGMA_THREADPRIVATE,
05951 WN_st_idx(thread_priv_prag),
05952 WN_pragma_arg1(thread_priv_prag),
05953 WN_pragma_arg2(thread_priv_prag) ));
05954 }
05955 thread_priv_prag = WN_next(thread_priv_prag);
05956 }
05957
05958 Gen_Threadpriv_Func (prags, body, TRUE);
05959
05960
05961 WN * prag_iter, * next_prag_iter = WN_first (prags);
05962 while (prag_iter = next_prag_iter )
05963 {
05964 next_prag_iter = WN_next (prag_iter);
05965
05966 if (WN_operator (prag_iter) == OPR_PRAGMA &&
05967 WN_pragma (prag_iter) == WN_PRAGMA_LOCAL)
05968 {
05969 WN * wn = NULL;
05970 for (wn = local_nodes; wn; wn = WN_next(wn))
05971 if (Identical_Pragmas(prag_iter, wn))
05972 break;
05973 if (wn == NULL)
05974 {
05975 prag_iter = WN_EXTRACT_FromBlock (prags, prag_iter);
05976 WN_next(prag_iter) = local_nodes;
05977 local_nodes = prag_iter;
05978 ++local_count;
05979 } else
05980 WN_DELETE_FromBlock (prags, prag_iter);
05981 }
05982 }
05983
05984
05985 parallel_proc = NULL;
05986
05987 INT32 vsize = (local_count + 1) * sizeof(VAR_TABLE);
05988 var_table = (VAR_TABLE *) alloca (vsize);
05989 BZERO (var_table, vsize);
05990
05991 mpt = MPP_ORPHAN;
05992
05993 Create_Local_Variables (var_table, NULL, NULL, local_nodes, NULL,
05994 &firstprivate_block, NULL, &alloca_block);
05995 Localize_Parent_Stack lps (FALSE, NULL);
05996 Walk_and_Localize (body, var_table, &lps, FALSE, &non_pod_finalization_nodes);
05997
05998 localized_var_vect.clear();
05999
06000
06001 WN * next_node;
06002 while (local_nodes) {
06003 next_node = WN_next (local_nodes);
06004 WN_Delete (local_nodes);
06005 local_nodes = next_node;
06006 }
06007 }
06008 #endif
06009
06010
06011
06012
06013 static WN *
06014 Gen_MP_Copyin ( BOOL is_omp )
06015 {
06016 WN *wn;
06017 WN *wnx;
06018 WN *wny;
06019 #ifdef KEY
06020 WN *wnz;
06021 #endif
06022 TY_IDX ty;
06023 INT32 kid;
06024 INT32 size;
06025 BOOL have_pods = FALSE;
06026 BOOL have_nonpods = FALSE;
06027 INT count = 0;
06028 WN *block = WN_CreateBlock();
06029
06030
06031
06032
06033 for (wnx = copyin_nodes; wnx; wnx = WN_next(wnx)) {
06034
06035 if (is_omp && is_omp_non_pod_copyin(wnx)) {
06036
06037
06038
06039 have_nonpods = TRUE;
06040 }
06041 else {
06042
06043 count++;
06044 have_pods = TRUE;
06045 }
06046 }
06047
06048 if (have_pods) {
06049 #ifdef KEY
06050 wn = WN_Create ( OPC_VCALL, 3 * count + 1 );
06051 WN_st_idx(wn) = GET_MPRUNTIME_ST(MPR_OMP_COPYIN_THDPRV);
06052 #else
06053 wn = WN_Create ( OPC_VCALL, 2 * count + 1 );
06054 WN_st_idx(wn) = (is_omp ? GET_MPRUNTIME_ST (MPR_OMP_COPYIN) :
06055 GET_MPRUNTIME_ST ( MPR_COPYIN ));
06056 #endif
06057 WN_Set_Call_Non_Data_Mod ( wn );
06058 WN_Set_Call_Non_Data_Ref ( wn );
06059 WN_Set_Call_Non_Parm_Mod ( wn );
06060 WN_Set_Call_Non_Parm_Ref ( wn );
06061 WN_Set_Call_Parm_Mod ( wn );
06062 WN_Set_Call_Parm_Ref ( wn );
06063 WN_linenum(wn) = line_number;
06064
06065 #ifdef KEY
06066
06067 WN_kid0(wn) = WN_CreateParm ( MTYPE_I4,
06068 WN_Intconst ( MTYPE_I4, 3 * count ),
06069 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE );
06070 for (wnx = copyin_nodes, kid = 1; wnx; wnx = WN_next(wnx), kid += 3)
06071 #else
06072 WN_kid0(wn) = WN_CreateParm ( MTYPE_I4,
06073 WN_Intconst ( MTYPE_I4, count ),
06074 Be_Type_Tbl(MTYPE_I4), WN_PARM_BY_VALUE );
06075 for (wnx = copyin_nodes, kid = 1; wnx; wnx = WN_next(wnx), kid += 2)
06076 #endif
06077 {
06078
06079 if (is_omp && is_omp_non_pod_copyin(wnx)) {
06080 continue;
06081 }
06082 #ifdef KEY
06083 if (WN_opcode(wnx) == OPC_PRAGMA) {
06084 ST *ppthd, *global;
06085 global = Get_Threadprv_St(reference_block, WN_st(wnx), &ppthd);
06086 wny = WN_CreateLdid(OPCODE_make_op(OPR_LDID,
06087 Pointer_type, Pointer_type),
06088 0, ppthd,ST_type(ppthd));
06089
06090
06091 wnz = WN_IloadLdid(TY_mtype(ST_type(global)), 0,
06092 ST_type(global), global, 0);
06093 ty = ST_type(WN_st(wnx));
06094 size = TY_size(ty);
06095 } else
06096 Fail_FmtAssertion ( "bad copyin node (%s) in MP processing",
06097 OPCODE_name(WN_opcode(WN_kid0(wnx))) );
06098 WN_kid(wn,kid) = WN_CreateParm ( Pointer_type, wny,
06099 Make_Pointer_Type ( ty,
06100 FALSE ),
06101 WN_PARM_BY_REFERENCE );
06102 WN_kid(wn,kid+1) = WN_CreateParm ( Pointer_type, wnz,
06103 Make_Pointer_Type ( ty,
06104 FALSE ),
06105 WN_PARM_BY_REFERENCE );
06106 WN_kid(wn,kid+2) = WN_CreateParm ( MTYPE_I4,
06107 WN_Intconst ( MTYPE_I4, size ),
06108 Be_Type_Tbl(MTYPE_I4),
06109 WN_PARM_BY_VALUE );
06110 #else
06111 if (WN_opcode(wnx) == OPC_PRAGMA) {
06112 wny = WN_Lda ( Pointer_type, WN_offsetx(wnx), WN_st(wnx) );
06113 ty = ST_type(WN_st(wnx));
06114 size = TY_size(ty);
06115 } else if (WN_operator(WN_kid0(wnx)) == OPR_LDA) {
06116 wny = WN_COPY_Tree ( WN_kid0(wnx) );
06117 ty = ST_type(WN_st(WN_kid0(wnx)));
06118 size = TY_size(ty);
06119 } else if ((WN_operator(WN_kid0(wnx)) == OPR_ARRAY) &&
06120 (WN_operator(WN_kid0(WN_kid0(wnx))) == OPR_LDA)) {
06121 wny = WN_COPY_Tree ( WN_kid0(wnx) );
06122 ty = TY_AR_etype(ST_type(WN_st(WN_kid0(WN_kid0(wnx)))));
06123 size = TY_size(ty);
06124 } else
06125 Fail_FmtAssertion ( "bad copyin node (%s) in MP processing",
06126 OPCODE_name(WN_opcode(WN_kid0(wnx))) );
06127
06128 WN_kid(wn,kid) = WN_CreateParm ( Pointer_type, wny,
06129 Make_Pointer_Type ( ty,
06130 FALSE ),
06131 WN_PARM_BY_REFERENCE );
06132 WN_kid(wn,kid+1) = WN_CreateParm ( MTYPE_I4,
06133 WN_Intconst ( MTYPE_I4, size ),
06134 Be_Type_Tbl(MTYPE_I4),
06135 WN_PARM_BY_VALUE );
06136 #endif
06137 }
06138 WN_INSERT_BlockFirst (block, wn);
06139 #ifdef KEY
06140
06141
06142 WN_INSERT_BlockAfter (block, wn, Gen_Barrier (local_gtid));
06143 #endif // KEY
06144 }
06145
06146 if (have_nonpods) {
06147
06148 for (wnx = copyin_nodes; wnx; wnx = WN_next(wnx)) {
06149
06150 if (!(is_omp && is_omp_non_pod_copyin(wnx))) {
06151 continue;
06152 }
06153
06154 ST* st = WN_st(wnx);
06155 TY_IDX ty = ST_type(st);
06156
06157 if (TY_kind(ty) != KIND_ARRAY) {
06158
06159
06160
06161 wn = WN_Create (OPC_VCALL, 2);
06162 WN_st_idx(wn) = (GET_MPRUNTIME_ST (MPR_OMP_NONPOD_COPYIN));
06163 WN_Set_Call_Non_Data_Mod ( wn );
06164 WN_Set_Call_Non_Data_Ref ( wn );
06165 WN_Set_Call_Non_Parm_Mod ( wn );
06166 WN_Set_Call_Non_Parm_Ref ( wn );
06167 WN_Set_Call_Parm_Mod ( wn );
06168 WN_Set_Call_Parm_Ref ( wn );
06169 WN_linenum(wn) = line_number;
06170
06171
06172 WN *obj = WN_CreateLda (OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V),
06173 0,
06174 Make_Pointer_Type(ty,FALSE),
06175 st);
06176 WN_kid0(wn) = WN_CreateParm (Pointer_type,
06177 obj,
06178 Make_Pointer_Type(ty, FALSE),
06179 WN_PARM_BY_REFERENCE);
06180
06181 FmtAssert (ST_export(WN_st(WN_kid0(wnx))) == EXPORT_PREEMPTIBLE,
06182 ("COPYIN (%s) requires a pre-emptible assignment operator",
06183 ST_name(st)));
06184 WN_kid1(wn) = WN_CreateParm(Pointer_type,
06185 WN_COPY_Tree(WN_kid0(wnx)),
06186 WN_ty(WN_kid0(wnx)),
06187 WN_PARM_BY_REFERENCE);
06188 }
06189 else {
06190
06191
06192
06193
06194
06195 wn = WN_Create (OPC_VCALL, 4);
06196 WN_st_idx(wn) = (GET_MPRUNTIME_ST (MPR_OMP_NONPOD_ARRAY_COPYIN));
06197 WN_Set_Call_Non_Data_Mod ( wn );
06198 WN_Set_Call_Non_Data_Ref ( wn );
06199 WN_Set_Call_Non_Parm_Mod ( wn );
06200 WN_Set_Call_Non_Parm_Ref ( wn );
06201 WN_Set_Call_Parm_Mod ( wn );
06202 WN_Set_Call_Parm_Ref ( wn );
06203 WN_linenum(wn) = line_number;
06204
06205
06206 WN *obj = WN_CreateLda (OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V),
06207 0,
06208 Make_Pointer_Type(ty, FALSE),
06209 st);
06210 WN_kid(wn,0) = WN_CreateParm (Pointer_type,
06211 obj,
06212 Make_Pointer_Type(ty, FALSE),
06213 WN_PARM_BY_REFERENCE);
06214
06215
06216
06217
06218
06219 FmtAssert (ST_export(WN_st(WN_kid0(wnx))) == EXPORT_PREEMPTIBLE,
06220 ("COPYIN (%s) requires a pre-emptible assignment operator",
06221 ST_name(st)));
06222 WN_kid(wn,1) = WN_CreateParm(Pointer_type,
06223 WN_COPY_Tree(WN_kid0(wnx)),
06224 WN_ty(WN_kid0(wnx)),
06225 WN_PARM_BY_REFERENCE);
06226
06227
06228 INT size;
06229 size = TY_size(TY_AR_etype(ty));
06230 WN_kid(wn,2) = WN_CreateParm(MTYPE_I8,
06231 WN_CreateIntconst (OPC_I8INTCONST,size),
06232 Be_Type_Tbl(MTYPE_I8),
06233 WN_PARM_BY_VALUE);
06234
06235
06236 INT64 num_elems = 1;
06237 for (INT i=0; i<TY_AR_ndims(ty); i++) {
06238
06239 FmtAssert (TY_AR_const_ubnd(ty,i) &&
06240 TY_AR_const_lbnd(ty,i) &&
06241 TY_AR_const_stride(ty,i),
06242 ("COPYIN array (%s) has non-const bounds. Weird!\n",
06243 ST_name(st)));
06244
06245 num_elems = num_elems * (TY_AR_ubnd_val(ty,i) -
06246 TY_AR_lbnd_val(ty,i) + 1);
06247 }
06248 WN* elems = WN_CreateIntconst(OPC_I8INTCONST,num_elems);
06249 WN_kid(wn,3) = WN_CreateParm(MTYPE_I8,
06250 elems,
06251 Be_Type_Tbl(MTYPE_I8),
06252 WN_PARM_BY_VALUE);
06253 }
06254
06255 WN_INSERT_BlockLast (block, wn);
06256 }
06257 }
06258
06259 return (block);
06260 }
06261
06262 #define MAX_NDIM 7
06263
06264
06265
06266
06267
06268
06269 static WN *
06270 create_doloop_node(WN *index_id, WN *start, WN *end,
06271 WN *step, WN *body, BOOL add_prompf=FALSE)
06272 {
06273 WN *temp;
06274 WN_Set_Linenum(start,line_number);
06275 WN_Set_Linenum(step,line_number);
06276 temp = WN_CreateDO(index_id, start, end, step, body, NULL);
06277 WN_Set_Linenum(temp,line_number);
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293 return (temp);
06294 }
06295
06296
06297
06298
06299
06300
06301
06302
06303
06304
06305
06306
06307
06308 static WN *
06309 create_doloop(PREG_NUM *index, char *index_name,
06310 WN *count, WN *body)
06311 {
06312 WN *index_id, *count_expr, *start, *end, *step, *doloop;
06313 OPCODE intconst_op;
06314 TYPE_ID index_type;
06315 WN *temp;
06316
06317
06318
06319
06320
06321 index_type= MTYPE_I8;
06322 intconst_op = OPCODE_make_op(OPR_INTCONST,index_type,MTYPE_V);
06323
06324
06325 *index = Create_Preg(index_type,Index_To_Str(Save_Str(index_name)));
06326
06327 index_id = WN_CreateIdname(*index,MTYPE_To_PREG(index_type));
06328 count_expr = WN_CreateExp2(OPCODE_make_op(OPR_SUB,index_type,MTYPE_V),
06329 count, WN_CreateIntconst(intconst_op,1));
06330
06331 start = WN_StidPreg(index_type,*index,
06332 WN_CreateIntconst(intconst_op,0));
06333 end = WN_CreateExp2(OPCODE_make_op(OPR_LE,MTYPE_I4,index_type),
06334 WN_LdidPreg(index_type,*index),
06335 count_expr);
06336
06337 step = WN_CreateExp2(OPCODE_make_op(OPR_ADD,index_type,MTYPE_V),
06338 WN_LdidPreg(index_type,*index),
06339 WN_CreateIntconst(intconst_op,1));
06340
06341 step = WN_StidPreg(index_type,*index,step);
06342
06343
06344 if (WN_opcode(body) != OPC_BLOCK)
06345 {
06346 temp = WN_CreateBlock();
06347 WN_INSERT_BlockFirst(temp,body);
06348 }
06349 else
06350 {
06351 temp = body;
06352 }
06353
06354 doloop = create_doloop_node(index_id, start,
06355 end, step, temp);
06356 return doloop;
06357 }
06358
06359
06360
06361
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371 static WN *
06372 create_doloop_nest(PREG_NUM indices[], WN **doloop, WN *sizes[], INT ndim)
06373 {
06374 INT i;
06375 WN *loopnest, *stlist;
06376 char tempname[32];
06377 static int num_temps = 0;
06378 PREG_NUM index;
06379
06380 loopnest = WN_CreateBlock();
06381 stlist = loopnest;
06382 num_temps += 1;
06383 for (i=ndim-1; i >= 0; i--)
06384 {
06385 sprintf(tempname,"@f90li_%d_%d",i,num_temps);
06386
06387
06388 loopnest = create_doloop(&index,tempname,
06389 sizes[i],loopnest);
06390 indices[i] = index;
06391 }
06392 *doloop = loopnest;
06393 return stlist;
06394
06395 }
06396
06397
06398
06399
06400
06401
06402
06403
06404
06405
06406
06407
06408
06409
06410
06411 extern INT
06412 MP_Reduction_Combine_Cycles(REDUCTION_LIST *rlist, BOOL *using_critical)
06413 {
06414
06415 *using_critical = TRUE;
06416 return 0;
06417
06418
06419 Is_True(rlist->Elements() > 0, ("no reductions"));
06420
06421 const double cycle_time = 1 / 250.0e6;
06422 const double crit_time = 20.6e-6;
06423 const double cas_time = 8.9e-6;
06424 const double fop_time = 8.4e-6;
06425
06426 INT tot_cycles = 0, i;
06427
06428 *using_critical = TRUE;
06429
06430 #ifdef TARG_IA32
06431 return tot_cycles;
06432 #endif
06433
06434 if (rlist->Elements() > 2) {
06435 return (INT)(crit_time / cycle_time);
06436 }
06437
06438
06439 for (i = 0; i < rlist->Elements(); i++) {
06440 OPERATOR oper = WN_operator(WN_kid0((*rlist)[i]));
06441 if (oper == OPR_CAND || oper == OPR_CIOR)
06442 return (INT)(crit_time / cycle_time);
06443 }
06444
06445 for (i = 0; i < rlist->Elements(); i++) {
06446 switch (WN_ATOMIC_STORE_Lowering_Class((*rlist)[i])) {
06447 case ALCLASS_SWAP:
06448 tot_cycles += (INT)(cas_time / cycle_time);
06449 break;
06450 case ALCLASS_DIRECT:
06451 tot_cycles += (INT)(fop_time / cycle_time);
06452 break;
06453 case ALCLASS_CRITICAL:
06454 return (INT)(crit_time / cycle_time);
06455 default:
06456 Fail_FmtAssertion("bogus ATOMIC_Lowering_Class");
06457 }
06458 }
06459
06460 *using_critical = FALSE;
06461 return tot_cycles;
06462 }
06463
06464
06465
06466
06467
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479 static void
06480 Gen_MP_Reduction(VAR_TABLE *var_table, INT num_vars, WN **init_block,
06481 WN **store_block)
06482 {
06483 INT i, num_redns = 0;
06484 VAR_TABLE *v;
06485 WN *sizes[MAX_NDIM];
06486 WN *sizes_bak[MAX_NDIM];
06487 PREG_NUM new_indices[MAX_NDIM];
06488 INT ndim_array;
06489 WN *loopnest;
06490 WN *stlist;
06491 WN *temp;
06492
06493
06494 *init_block = WN_CreateBlock ( );
06495 *store_block = WN_CreateBlock ( );
06496
06497
06498 for (i = 0, v = var_table; i < num_vars; i++, v++)
06499 if (v->vtype == VAR_REDUCTION_SCALAR ||
06500 v->vtype == VAR_REDUCTION_ARRAY ||
06501 v->vtype == VAR_REDUCTION_ARRAY_OMP )
06502 {
06503
06504 num_redns++;
06505
06506 if(v->vtype == VAR_REDUCTION_ARRAY_OMP)
06507 {
06508
06509
06510
06511
06512 ARB_HANDLE arb_base = TY_arb( ST_type( v->new_st ));
06513 ndim_array = ARB_dimension( arb_base );
06514 Is_True(( ndim_array <= MAX_NDIM ) && ( ndim_array >= 0 ),
06515 ("dimension of array is not 0-7"));
06516
06517 INT64 temp_size = 0;
06518 for(int j=0; j<ndim_array; j++)
06519 {
06520 ARB_HANDLE arb = arb_base[ ndim_array-1-j ];
06521 Is_True( ARB_const_lbnd( arb ) && ARB_const_ubnd( arb ),
06522 ("Lower and/or Upper bound of array is not const"));
06523 temp_size = ARB_ubnd_val( arb ) - ARB_lbnd_val( arb ) + 1;
06524 temp_size = ( temp_size > 0 ) ? temp_size : 0;
06525 sizes[ndim_array-j-1] = WN_CreateIntconst( OPC_I8INTCONST,
06526 temp_size );
06527 sizes_bak[j] = WN_CreateIntconst( OPC_I8INTCONST, temp_size );
06528 }
06529
06530 for( int j=ndim_array; j<MAX_NDIM; j++ )
06531 {
06532 sizes[j] = NULL;
06533 sizes_bak[j] = NULL;
06534 }
06535
06536 stlist = create_doloop_nest( new_indices,&loopnest,
06537 sizes,ndim_array );
06538 WN_linenum( loopnest ) = line_number;
06539
06540
06541
06542 WN *wn_init_val = Make_Reduction_Identity( v->reduction_opr, v->mtype );
06543
06544
06545 OPCODE op_array = OPCODE_make_op( OPR_ARRAY, Pointer_type, MTYPE_V );
06546 WN *local_array = WN_Create( op_array, 1+2*ndim_array );
06547 WN_element_size( local_array ) = TY_size( TY_AR_etype( v->ty ));
06548
06549 WN_array_base( local_array ) = WN_CreateLda(
06550 OPCODE_make_op( OPR_LDA, Pointer_type, MTYPE_V ),
06551 0, Make_Pointer_Type( v->ty ), v->new_st);
06552
06553 for( int j=0; j<ndim_array; j++ )
06554 {
06555
06556
06557 WN_array_index( local_array, j ) = WN_LdidPreg( MTYPE_I8,
06558 new_indices[j] );
06559 WN_array_dim( local_array, j ) = sizes_bak[ndim_array-j-1];
06560 }
06561
06562
06563 WN *wn_store_val = WN_Istore( v->mtype, 0,
06564 Make_Pointer_Type( v->ty ),
06565 local_array, wn_init_val );
06566
06567 WN_INSERT_BlockLast( stlist, wn_store_val );
06568 WN_INSERT_BlockLast( *init_block, loopnest );
06569
06570 }
06571 else
06572 {
06573 WN_INSERT_BlockLast(*init_block,
06574 Gen_MP_Store(v->new_st, v->new_offset,
06575 Make_Reduction_Identity(v->reduction_opr, v->mtype), TRUE));
06576 }
06577 }
06578
06579 Is_True(num_redns > 0, ("no reductions!"));
06580
06581
06582 BOOL lower_using_critical = FALSE;
06583 for (i = 0, v = var_table; i < num_vars; i++, v++)
06584 {
06585 if (v->vtype == VAR_REDUCTION_SCALAR ||
06586 v->vtype == VAR_REDUCTION_ARRAY) {
06587
06588
06589 WN *orig_val = (v->vtype == VAR_REDUCTION_SCALAR) ?
06590 Gen_MP_Load(v->orig_st, v->orig_offset, TRUE) :
06591 WN_Iload(v->mtype, 0, v->ty, WN_COPY_Tree(v->vtree));
06592 WN *new_val = Gen_MP_Load(v->new_st, v->new_offset, TRUE);
06593 if ( (v->reduction_opr == OPR_CAND || v->reduction_opr == OPR_CIOR) &&
06594 (v->mtype == MTYPE_F4 || v->mtype == MTYPE_F8 ||
06595 v->mtype == MTYPE_F10 || v->mtype == MTYPE_FQ) ) {
06596
06597 orig_val = WN_NE(v->mtype, orig_val,
06598 Make_Const(Host_To_Targ_Float(v->mtype, 0.0)));
06599 new_val = WN_NE(v->mtype, new_val,
06600 Make_Const(Host_To_Targ_Float(v->mtype, 0.0)));
06601 }
06602 WN *result = WN_CreateExp2(Make_Final_Reduction_Op(v->reduction_opc),
06603 orig_val, new_val);
06604
06605
06606
06607 TYPE_ID restype = OPCODE_rtype(v->reduction_opc);
06608 switch (v->mtype) {
06609 case MTYPE_I1:
06610 result = WN_CreateCvtl(OPC_I4CVTL, 8, result);
06611 restype = MTYPE_I4;
06612 break;
06613 case MTYPE_I2:
06614 result = WN_CreateCvtl(OPC_I4CVTL, 16, result);
06615 restype = MTYPE_I4;
06616 break;
06617 case MTYPE_U1:
06618 result = WN_CreateCvtl(OPC_U4CVTL, 8, result);
06619 restype = MTYPE_U4;
06620 break;
06621 case MTYPE_U2:
06622 result = WN_CreateCvtl(OPC_U4CVTL, 16, result);
06623 restype = MTYPE_U4;
06624 break;
06625 }
06626 if ((( restype == MTYPE_I4 || restype == MTYPE_I8 ||
06627 restype == MTYPE_U4 || restype == MTYPE_U8 ) &&
06628 ( v->mtype == MTYPE_F4 || v->mtype == MTYPE_F8 ||
06629 v->mtype == MTYPE_F10 || v->mtype == MTYPE_FQ)) ||
06630 (( v->mtype == MTYPE_I4 || v->mtype == MTYPE_I8 ||
06631 v->mtype == MTYPE_U4 || v->mtype == MTYPE_U8 ) &&
06632 ( restype == MTYPE_F4 || restype == MTYPE_F8 ||
06633 restype == MTYPE_F10 || restype == MTYPE_FQ )))
06634 result = WN_Cvt(restype, v->mtype, result);
06635 else if ((restype == MTYPE_I4 || restype == MTYPE_I8 ||
06636 restype == MTYPE_U4 || restype == MTYPE_U8) &&
06637 (v->mtype == MTYPE_I4 || v->mtype == MTYPE_I8 ||
06638 v->mtype == MTYPE_U4 || v->mtype == MTYPE_U8) &&
06639 v->mtype != restype)
06640 result = WN_Cvt(restype, v->mtype, result);
06641
06642
06643
06644 if (v->vtype == VAR_REDUCTION_SCALAR) {
06645 WN_INSERT_BlockLast(*store_block,
06646 Gen_MP_Store(v->orig_st, v->orig_offset, result, TRUE));
06647
06648
06649
06650
06651
06652 } else {
06653 WN_INSERT_BlockLast(*store_block,
06654 WN_Istore(v->mtype, 0,
06655 Make_Pointer_Type(v->ty, FALSE),
06656 WN_COPY_Tree(v->vtree), result ));
06657 }
06658
06659 }else if(v->vtype == VAR_REDUCTION_ARRAY_OMP) {
06660
06661
06662 lower_using_critical = TRUE;
06663
06664
06665 ARB_HANDLE arb_base = TY_arb( ST_type( v->new_st ));
06666 ndim_array = ARB_dimension( arb_base );
06667 Is_True(( ndim_array <= MAX_NDIM ) && ( ndim_array >= 0 ),
06668 ("dimension of array is not 0-7"));
06669
06670 INT64 temp_size = 0;
06671 for(int j=0; j<ndim_array; j++)
06672 {
06673 ARB_HANDLE arb = arb_base[ ndim_array-1-j ];
06674 Is_True( ARB_const_lbnd( arb ) && ARB_const_ubnd( arb ),
06675 ("Lower and/or Upper bound of array is not const"));
06676 temp_size = ARB_ubnd_val( arb ) - ARB_lbnd_val( arb ) + 1;
06677 temp_size = ( temp_size > 0 ) ? temp_size : 0;
06678 sizes[ndim_array-j-1] = WN_CreateIntconst( OPC_I8INTCONST,
06679 temp_size );
06680 sizes_bak[j] = WN_CreateIntconst( OPC_I8INTCONST, temp_size );
06681 }
06682
06683 for( int j=ndim_array; j<MAX_NDIM; j++ )
06684 {
06685 sizes[j] = NULL;
06686 sizes_bak[j] = NULL;
06687 }
06688
06689 stlist = create_doloop_nest( new_indices,&loopnest,
06690 sizes,ndim_array );
06691 WN_linenum( loopnest ) = line_number;
06692
06693 WN *wn_init_val = Make_Reduction_Identity( v->reduction_opr, v->mtype );
06694 OPCODE op_array = OPCODE_make_op( OPR_ARRAY, Pointer_type, MTYPE_V );
06695 WN *new_array = WN_Create( op_array, 1+2*ndim_array );
06696 WN_element_size( new_array ) = TY_size( TY_AR_etype( v->ty ));
06697 WN_array_base( new_array ) = WN_Lda( Pointer_type, 0, v->new_st );
06698
06699 WN *old_array = WN_Create( op_array, 1+2*ndim_array );
06700 WN_element_size( old_array ) = TY_size( TY_AR_etype( v->ty ));
06701 WN_array_base( old_array ) = WN_Lda( Pointer_type, 0, v->orig_st );
06702
06703 for( int j=0; j<ndim_array; j++ )
06704 {
06705
06706
06707 WN_array_index( new_array, j ) = WN_LdidPreg( MTYPE_I8, new_indices[j] );
06708 WN_array_dim( new_array, j ) = WN_COPY_Tree( sizes_bak[ndim_array-j-1] );
06709 WN_array_index( old_array, j ) = WN_LdidPreg( MTYPE_I8, new_indices[j] );
06710 WN_array_dim( old_array, j ) = sizes_bak[ndim_array-j-1];
06711 }
06712
06713 WN *wn_old_val = WN_Iload( v->mtype, 0, Make_Pointer_Type( v->ty ),
06714 WN_COPY_Tree( old_array ));
06715 WN *wn_new_val = WN_Iload( v->mtype, 0, Make_Pointer_Type( v->ty ),
06716 new_array );
06717
06718 if(( v->reduction_opr == OPR_CAND || v->reduction_opr == OPR_CIOR) &&
06719 ( v->mtype == MTYPE_F4 || v->mtype == MTYPE_F8 ||
06720 v->mtype == MTYPE_F10 || v->mtype == MTYPE_FQ ))
06721 {
06722 wn_old_val = WN_NE( v->mtype, wn_old_val,
06723 Make_Const( Host_To_Targ_Float( v->mtype, 0.0 )));
06724 wn_new_val = WN_NE( v->mtype, wn_new_val,
06725 Make_Const( Host_To_Targ_Float( v->mtype, 0.0 )));
06726 }
06727 WN *result = WN_CreateExp2( Make_Final_Reduction_Op( v->reduction_opc ),
06728 wn_old_val, wn_new_val );
06729
06730 TYPE_ID restype = OPCODE_rtype(v->reduction_opc);
06731 switch (v->mtype) {
06732 case MTYPE_I1:
06733 result = WN_CreateCvtl(OPC_I4CVTL, 8, result);
06734 restype = MTYPE_I4;
06735 break;
06736 case MTYPE_I2:
06737 result = WN_CreateCvtl(OPC_I4CVTL, 16, result);
06738 restype = MTYPE_I4;
06739 break;
06740 case MTYPE_U1:
06741 result = WN_CreateCvtl(OPC_U4CVTL, 8, result);
06742 restype = MTYPE_U4;
06743 break;
06744 case MTYPE_U2:
06745 result = WN_CreateCvtl(OPC_U4CVTL, 16, result);
06746 restype = MTYPE_U4;
06747 break;
06748 }
06749 if((( restype == MTYPE_I4 || restype == MTYPE_I8 ||
06750 restype == MTYPE_U4 || restype == MTYPE_U8 ) &&
06751 ( v->mtype == MTYPE_F4 || v->mtype == MTYPE_F8 ||
06752 v->mtype == MTYPE_F10 || v->mtype == MTYPE_FQ )) ||
06753 (( v->mtype == MTYPE_I4 || v->mtype == MTYPE_I8 ||
06754 v->mtype == MTYPE_U4 || v->mtype == MTYPE_U8 ) &&
06755 ( restype == MTYPE_F4 || restype == MTYPE_F8 ||
06756 restype == MTYPE_F10 || restype == MTYPE_FQ )))
06757 result = WN_Cvt( restype, v->mtype, result );
06758 else if(( restype == MTYPE_I4 || restype == MTYPE_I8 ||
06759 restype == MTYPE_U4 || restype == MTYPE_U8) &&
06760 ( v->mtype == MTYPE_I4 || v->mtype == MTYPE_I8 ||
06761 v->mtype == MTYPE_U4 || v->mtype == MTYPE_U8 ) &&
06762 v->mtype != restype )
06763 result = WN_Cvt( restype, v->mtype, result );
06764
06765 WN *wn_store_val = WN_Istore( v->mtype, 0, Make_Pointer_Type( v->ty ),
06766 old_array, result );
06767 WN_INSERT_BlockLast( stlist, wn_store_val );
06768 WN_INSERT_BlockLast( *store_block, loopnest );
06769
06770 }
06771 }
06772
06773 WN *unlock = NULL;
06774
06775 if (!unlock)
06776 {
06777
06778 ST *mplock = Create_Critical_Lock( );
06779 WN_INSERT_BlockFirst( *store_block,
06780 Gen_Critical( local_gtid, mplock ));
06781 unlock = Gen_End_Critical ( local_gtid, mplock );
06782 WN_INSERT_BlockLast( *store_block, unlock );
06783
06784 WN_INSERT_BlockLast( *store_block, Gen_Barrier(local_gtid));
06785 }
06786 }
06787
06788 static WN*
06789 WN_Integer_Cast(WN* tree, TYPE_ID to, TYPE_ID from)
06790 {
06791 if (from != to)
06792 return WN_CreateExp1(OPCODE_make_op(OPR_CVT, to, from), tree);
06793 else
06794 return tree;
06795 }
06796
06797
06798
06799
06800 static BOOL
06801 Calls_Alloca(WN *tree)
06802 {
06803 WN *kid;
06804 INT kidno;
06805 OPCODE opc;
06806
06807 Is_True(tree, ("NULL tree passed to Calls_Alloca()"));
06808
06809 opc = WN_opcode(tree);
06810 if ((opc == OPC_U4INTRINSIC_CALL &&
06811 WN_intrinsic(tree) == INTRN_U4I4ALLOCA) ||
06812 (opc == OPC_U8INTRINSIC_CALL &&
06813 WN_intrinsic(tree) == INTRN_U8I8ALLOCA)) {
06814 Is_True(!Alloca_Dealloca_On,
06815 ("Alloca_Dealloca_On yet found INTRN_ALLOCA"));
06816 return TRUE;
06817 }
06818
06819 if (WN_operator(tree) == OPR_ALLOCA) {
06820 Is_True(Alloca_Dealloca_On,
06821 ("found OPR_ALLOCA yet not Alloca_Dealloca_On"));
06822 return TRUE;
06823 }
06824
06825 if (!OPCODE_is_leaf(opc))
06826 if (opc == OPC_BLOCK) {
06827 for (kid = WN_first(tree); kid; kid = WN_next(kid))
06828 if (Calls_Alloca(kid))
06829 return TRUE;
06830
06831 } else {
06832 for (kidno = 0; kidno < WN_kid_count(tree); kidno++)
06833 if (Calls_Alloca(WN_kid(tree, kidno)))
06834 return TRUE;
06835 }
06836
06837 return FALSE;
06838 }
06839
06840
06841
06842
06843
06844
06845
06846
06847
06848
06849
06850
06851
06852
06853
06854
06855 static const char * const dope_str_prefix = ".dope." ;
06856 static const INT dope_str_prefix_len = 6;
06857
06858 static BOOL
06859 ST_Has_Dope_Vector(ST *st)
06860 {
06861 if (ST_class(st) != CLASS_VAR)
06862 return FALSE;
06863
06864 if ( TY_is_f90_pointer(Ty_Table[ST_type(*st)]) )
06865 return TRUE;
06866
06867 TY_IDX ty = ST_type(st);
06868 while (TY_kind(ty) == KIND_POINTER)
06869 ty = TY_pointed(ty);
06870
06871 if (TY_kind(ty) == KIND_STRUCT &&
06872 strncmp(TY_name(ty), dope_str_prefix, dope_str_prefix_len) == 0)
06873 return TRUE;
06874
06875 return FALSE;
06876 }
06877
06878
06879
06880
06881
06882
06883
06884 static WN *
06885 Gen_Save_Stack_Pointer(const char *st_basename, WN **sp_save_stid)
06886 {
06887 char *newstname;
06888 static INT count = 0;
06889 WN *save_block = WN_CreateBlock(), *preg_stid_kid;
06890
06891
06892 newstname = (char *) alloca(strlen(st_basename) + 32);
06893 sprintf(newstname, "$%s%d__$stkptr", st_basename, count++);
06894
06895 PREG_NUM sp_preg = Create_Preg(Pointer_type, (char *) newstname);
06896
06897 if (Alloca_Dealloca_On) {
06898
06899 preg_stid_kid = WN_CreateAlloca(WN_CreateIntconst(OPC_I4INTCONST, 0));
06900
06901 } else {
06902
06903 WN *intrin_call;
06904 intrin_call = WN_Create(OPCODE_make_op(OPR_INTRINSIC_CALL,
06905 Pointer_type, MTYPE_V), 0);
06906 WN_Set_Call_Non_Parm_Ref(intrin_call);
06907 WN_intrinsic(intrin_call) =
06908 (Pointer_Size == 8) ? INTRN_U8READSTACKPOINTER :
06909 INTRN_U4READSTACKPOINTER;
06910 WN_linenum(intrin_call) = line_number;
06911 WN_INSERT_BlockLast(save_block, intrin_call);
06912
06913
06914 PREG_NUM rreg1, rreg2;
06915
06916 GET_RETURN_PREGS(rreg1, rreg2, Pointer_type);
06917 preg_stid_kid = WN_LdidPreg(Pointer_type, rreg1);
06918 }
06919
06920 *sp_save_stid = WN_StidIntoPreg(Pointer_type, sp_preg,
06921 MTYPE_To_PREG(Pointer_type), preg_stid_kid);
06922 WN_linenum(*sp_save_stid) = line_number;
06923
06924 WN_INSERT_BlockLast(save_block, *sp_save_stid);
06925 return save_block;
06926 }
06927
06928
06929
06930
06931
06932 class Alloca_Var_List {
06933 public:
06934 struct Info {
06935 ST *st;
06936 WN_OFFSET offset;
06937 TY_IDX ty;
06938 Info(ST *_st, WN_OFFSET _ofs, TY_IDX _ty) : st(_st), offset(_ofs), ty(_ty)
06939 { }
06940 };
06941 private:
06942 DYN_ARRAY<Info> _list;
06943 public:
06944 Alloca_Var_List(WN *alloca_block);
06945 const DYN_ARRAY<Info> *list() const { return &_list; }
06946 };
06947
06948 Alloca_Var_List::Alloca_Var_List(WN *alloca_block) :
06949 _list(&mp_lower_pool)
06950 {
06951 Is_True(WN_operator(alloca_block) == OPR_BLOCK, ("not a BLOCK"));
06952
06953 if (!Alloca_Dealloca_On)
06954 return;
06955
06956 for (WN *kid = WN_first(alloca_block); kid; kid = WN_next(kid)) {
06957 OPERATOR opr = WN_operator(kid);
06958
06959 switch (opr) {
06960 case OPR_INTRINSIC_CALL:
06961 Is_True(WN_intrinsic(kid) == INTRN_U4I4ALLOCA ||
06962 WN_intrinsic(kid) == INTRN_U8I8ALLOCA, ("expected alloca()"));
06963 Is_True(!Alloca_Dealloca_On,
06964 ("Alloca_Dealloca_On yet found INTRN_ALLOCA"));
06965 break;
06966 case OPR_STID:
06967 _list.AddElement(Info(WN_st(kid), WN_offset(kid), WN_ty(kid)));
06968 break;
06969 default:
06970 Fail_FmtAssertion("unexpected opr == %d\n", (INT) opr);
06971 }
06972 }
06973 }
06974
06975
06976
06977
06978
06979 static WN *
06980 Gen_Restore_Stack_Pointer(WN *sp_save_stid, Alloca_Var_List *avlist)
06981 {
06982 WN *restore_block = WN_CreateBlock();
06983 WN *dealloca;
06984 WN *ldid_old_sp = WN_CreateLdid(
06985 OPCODE_make_op(OPR_LDID, Pointer_type, Pointer_type),
06986 WN_offset(sp_save_stid), WN_st(sp_save_stid), WN_ty(sp_save_stid));
06987
06988 if (Alloca_Dealloca_On) {
06989
06990 INT num_allocas = avlist->list()->Elements();
06991 dealloca = WN_CreateDealloca(num_allocas + 1);
06992 WN_kid0(dealloca) = ldid_old_sp;
06993
06994 for (INT i = 0; i < num_allocas; i++) {
06995 const Alloca_Var_List::Info *info = &(*avlist->list())[i];
06996 WN_kid(dealloca, i + 1) = WN_CreateLdid(
06997 OPCODE_make_op(OPR_LDID, Pointer_type, Pointer_type),
06998 info->offset, info->st, info->ty);
06999 }
07000
07001 } else {
07002
07003 dealloca = WN_Create(
07004 OPCODE_make_op(OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V), 1);
07005 WN_Set_Call_Non_Parm_Mod(dealloca);
07006 WN_Set_Call_Non_Parm_Ref(dealloca);
07007 WN_Set_Call_Parm_Ref(dealloca);
07008
07009 WN_intrinsic(dealloca) = (Pointer_Size == 8) ?
07010 INTRN_U8I8SETSTACKPOINTER : INTRN_U4I4SETSTACKPOINTER;
07011 WN_kid0(dealloca) = WN_CreateParm(Pointer_type, ldid_old_sp,
07012 Be_Type_Tbl(Pointer_type), WN_PARM_BY_VALUE );
07013 WN_linenum(dealloca) = line_number;
07014 }
07015
07016 WN_INSERT_BlockLast(restore_block, dealloca);
07017 return restore_block;
07018 }
07019
07020
07021
07022
07023
07024
07025
07026
07027 static WN *
07028 Gen_MP_SingleProcess_Block(WN *single_block, BOOL nowait,
07029 #ifdef KEY
07030 WN *copyprivates,
07031 #endif
07032 BOOL is_omp, BOOL is_orphaned)
07033 {
07034 WN *mp_single_block = WN_CreateBlock(), *return_stid, *single_test;
07035 WN *sp_block = WN_CreateBlock();
07036 ST *return_st;
07037 WN_OFFSET return_ofst;
07038 PREG_NUM rreg1, rreg2;
07039
07040 if( is_orphaned)
07041 {
07042
07043 WN_INSERT_BlockLast( mp_single_block, Gen_Store_Gtid());
07044 }
07045 WN_INSERT_BlockLast(mp_single_block,
07046 Gen_Single( WN_CreateIntconst(OPC_I4INTCONST, num_constructs),
07047 local_gtid, is_omp));
07048
07049 Create_Preg_or_Temp(MTYPE_I4, MPSP_STATUS_PREG_NAME, &return_st,
07050 &return_ofst);
07051 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
07052 return_stid = WN_Stid(MTYPE_I4, return_ofst, return_st, ST_type(return_st),
07053 WN_LdidPreg(MTYPE_I4, rreg1));
07054 WN_linenum(return_stid) = line_number;
07055 WN_INSERT_BlockLast(mp_single_block, return_stid);
07056
07057 WN *test = WN_EQ(MTYPE_I4,
07058 Gen_MP_Load( return_st, return_ofst ),
07059 WN_CreateIntconst ( OPC_I4INTCONST, 1));
07060 single_test = WN_CreateIf( test, single_block, WN_CreateBlock());
07061 WN_linenum(single_test) = line_number;
07062 WN_INSERT_BlockLast(mp_single_block, single_test);
07063 if (is_omp || !nowait)
07064 WN_INSERT_BlockLast(mp_single_block,
07065 Gen_End_Single(
07066 WN_CreateIntconst(OPC_I4INTCONST, num_constructs),
07067 local_gtid, is_omp, nowait));
07068 #ifdef KEY
07069 if (copyprivates)
07070 Gen_MP_Copyprivate(copyprivates, &mp_single_block, Gen_MP_Load( return_st, return_ofst ));
07071 #endif
07072
07073 return mp_single_block;
07074 }
07075
07076 #ifdef KEY
07077 static WN *
07078 Gen_MP_Workshare_Block(WN *workshare_block, BOOL nowait,
07079 BOOL is_omp, BOOL is_orphaned)
07080 {
07081 WN *mp_workshare_block = WN_CreateBlock(), *return_stid;
07082 WN *sp_block = WN_CreateBlock();
07083 ST *return_st;
07084 WN_OFFSET return_ofst;
07085 PREG_NUM rreg1, rreg2;
07086
07087 if( is_orphaned)
07088 {
07089
07090 WN_INSERT_BlockLast( mp_workshare_block, Gen_Store_Gtid());
07091 }
07092 WN_INSERT_BlockLast( mp_workshare_block, workshare_block);
07093
07094 if (is_omp || !nowait)
07095 WN_INSERT_BlockLast(mp_workshare_block, Gen_Barrier( local_gtid ));
07096
07097 return mp_workshare_block;
07098 }
07099
07100 static WN *Gen_MP_Workshare_Region(WN *workshare_region)
07101 {
07102 WN *prag = WN_first(WN_region_pragmas(workshare_region)), *workshare_prag = prag;
07103 WN *workshare_block = WN_region_body(workshare_region);
07104 VAR_TABLE *vt;
07105 WN_PRAGMA_ID prag_id;
07106 INT vt_size = 0, i;
07107 WN **nested_list, *wn, *nested_prag;
07108 WN *nested_local_nodes = NULL;
07109 BOOL nowait = FALSE;
07110 BOOL do_dealloca = FALSE;
07111 WN *mp_workshare_block = WN_CreateBlock();
07112 WN *sp_save_stid;
07113 Alloca_Var_List *avlist;
07114 BOOL is_orphaned = FALSE;
07115
07116 Is_True(mpt == MPP_WORKSHARE || mpt == MPP_ORPHANED_WORKSHARE,
07117 ("not inside a WORKSHARE"));
07118
07119 is_orphaned = ( mpt == MPP_WORKSHARE ) ? FALSE : TRUE;
07120
07121 if (mpt == MPP_ORPHANED_WORKSHARE) {
07122
07123 psymtab = CURRENT_SYMTAB;
07124 ppuinfo = Current_PU_Info;
07125 pmaptab = Current_Map_Tab;
07126 }
07127
07128 prag = WN_next(prag);
07129 WN_next(workshare_prag) = NULL;
07130 WN_last(WN_region_pragmas(workshare_region)) = workshare_prag;
07131
07132 while (prag)
07133 switch (prag_id = (WN_PRAGMA_ID) WN_pragma(prag)) {
07134 case WN_PRAGMA_LOCAL:
07135 nested_prag = prag;
07136 prag = WN_next(prag);
07137 nested_list = ( prag_id == WN_PRAGMA_LOCAL &&
07138 !ST_Has_Dope_Vector(WN_st(nested_prag)) ) ?
07139 &nested_local_nodes :
07140 &nested_firstprivate_nodes;
07141 for (wn = *nested_list; wn; wn = WN_next(wn))
07142 if (Identical_Pragmas(nested_prag, wn))
07143 break;
07144 if (!wn) {
07145 WN_next(nested_prag) = *nested_list;
07146 *nested_list = nested_prag;
07147 vt_size++;
07148 } else
07149 WN_Delete(nested_prag);
07150 break;
07151
07152 case WN_PRAGMA_SHARED:
07153 nested_prag = prag;
07154 prag = WN_next(prag);
07155 WN_Delete(nested_prag);
07156 break;
07157
07158 case WN_PRAGMA_NOWAIT:
07159 nowait = TRUE;
07160 nested_prag = prag;
07161 prag = WN_next(prag);
07162 WN_Delete(nested_prag);
07163 break;
07164
07165 case WN_PRAGMA_END_MARKER:
07166 nested_prag = prag;
07167 prag = WN_next(prag);
07168 WN_Delete(nested_prag);
07169 break;
07170
07171 default:
07172 Fail_FmtAssertion("illegal pragma type %d in SINGLE directive",
07173 WN_pragma(prag));
07174 }
07175
07176 WN_region_body(workshare_region) = NULL;
07177
07178 if (vt_size) {
07179 WN *nested_alloca_block = NULL;
07180
07181 vt = (VAR_TABLE *) alloca((vt_size + 1) * sizeof(VAR_TABLE));
07182 BZERO(vt, (vt_size + 1) * sizeof(VAR_TABLE));
07183 Create_Local_Variables(vt, NULL, NULL, nested_local_nodes,
07184 NULL, NULL,
07185 NULL, &nested_alloca_block);
07186
07187 Localize_Parent_Stack lps(mpt == MPP_ORPHANED_WORKSHARE, workshare_block);
07188 WN *nested_non_pod_finalization_nodes = NULL;
07189 Walk_and_Localize(workshare_block, vt, &lps, FALSE,
07190 &nested_non_pod_finalization_nodes);
07191
07192 if (nested_alloca_block) {
07193 if ((do_dealloca = !Calls_Alloca(workshare_block)) != 0) {
07194 WN_INSERT_BlockLast(mp_workshare_block,
07195 Gen_Save_Stack_Pointer("mpworkshare", &sp_save_stid));
07196 avlist = CXX_NEW(Alloca_Var_List(nested_alloca_block),
07197 &mp_lower_pool);
07198 }
07199 WN_INSERT_BlockLast(mp_workshare_block, nested_alloca_block);
07200 Set_PU_has_alloca(Get_Current_PU());
07201 }
07202
07203 for (i = 0; i < vt_size; i++) {
07204 if (vt[i].vtree)
07205 WN_DELETE_Tree(vt[i].vtree);
07206 if (vt[i].vtreex)
07207 WN_DELETE_Tree(vt[i].vtreex);
07208 }
07209 }
07210
07211 WN_INSERT_BlockLast(mp_workshare_block,
07212 Gen_MP_Workshare_Block(workshare_block, nowait,
07213 WN_pragma_omp(workshare_prag), is_orphaned ));
07214
07215 if (do_dealloca) {
07216 WN_INSERT_BlockLast(mp_workshare_block,
07217 Gen_Restore_Stack_Pointer(sp_save_stid, avlist));
07218 CXX_DELETE(avlist, &mp_lower_pool);
07219 }
07220
07221
07222 while (nested_local_nodes) {
07223 wn = WN_next(nested_local_nodes);
07224 WN_Delete(nested_local_nodes);
07225 nested_local_nodes = wn;
07226 }
07227 return mp_workshare_block;
07228 }
07229 #endif
07230
07231
07232
07233
07234
07235 static WN *Gen_MP_SingleProcess_Region(WN *single_region)
07236 {
07237 WN *prag = WN_first(WN_region_pragmas(single_region)), *single_prag = prag;
07238 WN *single_block = WN_region_body(single_region);
07239 VAR_TABLE *vt;
07240 WN_PRAGMA_ID prag_id;
07241 INT vt_size = 0, i;
07242 WN **nested_list, *wn, *nested_prag;
07243 WN *nested_local_nodes = NULL, *nested_firstprivate_nodes = NULL;
07244 #ifdef KEY
07245 WN *nested_copyprivate_nodes = NULL;
07246 #endif
07247 BOOL nowait = FALSE;
07248 BOOL do_dealloca = FALSE;
07249 WN *mp_single_block = WN_CreateBlock();
07250 WN *sp_save_stid;
07251 Alloca_Var_List *avlist;
07252 BOOL is_orphaned = FALSE;
07253
07254 Is_True(mpt == MPP_SINGLE || mpt == MPP_ORPHANED_SINGLE,
07255 ("not inside a SINGLE"));
07256
07257 is_orphaned = ( mpt == MPP_SINGLE ) ? FALSE : TRUE;
07258
07259 if (mpt == MPP_ORPHANED_SINGLE) {
07260
07261 psymtab = CURRENT_SYMTAB;
07262 ppuinfo = Current_PU_Info;
07263 pmaptab = Current_Map_Tab;
07264 }
07265
07266 prag = WN_next(prag);
07267 WN_next(single_prag) = NULL;
07268 WN_last(WN_region_pragmas(single_region)) = single_prag;
07269
07270 while (prag)
07271 switch (prag_id = (WN_PRAGMA_ID) WN_pragma(prag)) {
07272 case WN_PRAGMA_LOCAL:
07273 case WN_PRAGMA_FIRSTPRIVATE:
07274 #ifdef KEY
07275 case WN_PRAGMA_COPYPRIVATE:
07276 #endif
07277 nested_prag = prag;
07278 prag = WN_next(prag);
07279 #ifdef KEY
07280 if (prag_id == WN_PRAGMA_COPYPRIVATE)
07281 nested_list = &nested_copyprivate_nodes;
07282 else
07283 #endif
07284 nested_list = ( prag_id == WN_PRAGMA_LOCAL &&
07285 !ST_Has_Dope_Vector(WN_st(nested_prag)) ) ?
07286 &nested_local_nodes :
07287 &nested_firstprivate_nodes;
07288 for (wn = *nested_list; wn; wn = WN_next(wn))
07289 if (Identical_Pragmas(nested_prag, wn))
07290 break;
07291 if (!wn) {
07292 WN_next(nested_prag) = *nested_list;
07293 *nested_list = nested_prag;
07294 vt_size++;
07295 } else
07296 WN_Delete(nested_prag);
07297 break;
07298
07299
07300
07301 case WN_PRAGMA_SHARED:
07302 nested_prag = prag;
07303 prag = WN_next(prag);
07304 WN_Delete(nested_prag);
07305 break;
07306
07307 case WN_PRAGMA_NOWAIT:
07308 nowait = TRUE;
07309 nested_prag = prag;
07310 prag = WN_next(prag);
07311 WN_Delete(nested_prag);
07312 break;
07313
07314 case WN_PRAGMA_END_MARKER:
07315 nested_prag = prag;
07316 prag = WN_next(prag);
07317 WN_Delete(nested_prag);
07318 break;
07319
07320 default:
07321 Fail_FmtAssertion("illegal pragma type %d in SINGLE directive",
07322 WN_pragma(prag));
07323 }
07324
07325 WN_region_body(single_region) = NULL;
07326
07327 if (vt_size) {
07328 WN *nested_alloca_block = NULL, *firstprivate_block = NULL;
07329
07330 vt = (VAR_TABLE *) alloca((vt_size + 1) * sizeof(VAR_TABLE));
07331 BZERO(vt, (vt_size + 1) * sizeof(VAR_TABLE));
07332 Create_Local_Variables(vt, NULL, NULL, nested_local_nodes,
07333 nested_firstprivate_nodes, &firstprivate_block,
07334 NULL, &nested_alloca_block);
07335
07336 Localize_Parent_Stack lps(mpt == MPP_ORPHANED_SINGLE, single_block);
07337 WN *nested_non_pod_finalization_nodes = NULL;
07338 Walk_and_Localize(single_block, vt, &lps, FALSE,
07339 &nested_non_pod_finalization_nodes);
07340
07341
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355 if (nested_alloca_block) {
07356 if ((do_dealloca = !Calls_Alloca(single_block)) != 0) {
07357 WN_INSERT_BlockLast(mp_single_block,
07358 Gen_Save_Stack_Pointer("mpsingle", &sp_save_stid));
07359 avlist = CXX_NEW(Alloca_Var_List(nested_alloca_block),
07360 &mp_lower_pool);
07361 }
07362 WN_INSERT_BlockLast(mp_single_block, nested_alloca_block);
07363 Set_PU_has_alloca(Get_Current_PU());
07364 }
07365
07366 if (firstprivate_block)
07367 WN_INSERT_BlockLast(mp_single_block, firstprivate_block);
07368
07369 for (i = 0; i < vt_size; i++) {
07370 if (vt[i].vtree)
07371 WN_DELETE_Tree(vt[i].vtree);
07372 if (vt[i].vtreex)
07373 WN_DELETE_Tree(vt[i].vtreex);
07374 }
07375 }
07376
07377 #ifdef KEY
07378 WN_INSERT_BlockLast(mp_single_block,
07379 Gen_MP_SingleProcess_Block(single_block, nowait,
07380 nested_copyprivate_nodes,
07381 WN_pragma_omp(single_prag), is_orphaned ));
07382 #else
07383 WN_INSERT_BlockLast(mp_single_block,
07384 Gen_MP_SingleProcess_Block(single_block, nowait,
07385 WN_pragma_omp(single_prag), is_orphaned ));
07386 #endif
07387
07388 if (do_dealloca) {
07389 WN_INSERT_BlockLast(mp_single_block,
07390 Gen_Restore_Stack_Pointer(sp_save_stid, avlist));
07391 CXX_DELETE(avlist, &mp_lower_pool);
07392 }
07393
07394
07395 while (nested_local_nodes) {
07396 wn = WN_next(nested_local_nodes);
07397 WN_Delete(nested_local_nodes);
07398 nested_local_nodes = wn;
07399 }
07400 while (nested_firstprivate_nodes) {
07401 wn = WN_next(nested_firstprivate_nodes);
07402 WN_Delete(nested_firstprivate_nodes);
07403 nested_firstprivate_nodes = wn;
07404 }
07405 #ifdef KEY
07406 while (nested_copyprivate_nodes) {
07407 wn = WN_next(nested_copyprivate_nodes);
07408 WN_Delete(nested_copyprivate_nodes);
07409 nested_copyprivate_nodes = wn;
07410 }
07411 #endif
07412 return mp_single_block;
07413 }
07414
07415
07416
07417
07418
07419
07420
07421 static WN *Lower_Master( WN *master_region )
07422 {
07423 if (WN_opcode(master_region) != OPC_REGION) {
07424 return master_region;
07425 }
07426
07427 Is_True(mpt == MPP_MASTER || mpt == MPP_ORPHANED_MASTER,
07428 ("not inside a MASTER"));
07429
07430 WN *pragmas = WN_region_pragmas( master_region );
07431 INT pragma_count = 0;
07432 WN *wn = NULL;
07433 for ( wn = WN_first(pragmas); wn != NULL; wn = WN_next(wn))
07434 if (WN_opcode(wn) != OPC_PRAGMA
07435 || WN_pragma(wn) != WN_PRAGMA_END_MARKER)
07436 pragma_count++;
07437 Is_True( pragma_count == 1, ("OMP MASTER directive can not have subclauses. "));
07438
07439 WN *master_block = WN_region_body(master_region);
07440 WN *mp_master_block = WN_CreateBlock();
07441 BOOL is_orphaned = FALSE;
07442
07443 is_orphaned = ( mpt == MPP_MASTER ) ? FALSE : TRUE;
07444
07445 WN_region_body(master_region) = NULL;
07446
07447 if( is_orphaned == TRUE )
07448 {
07449 WN_INSERT_BlockLast( mp_master_block, Gen_Store_Gtid());
07450 }
07451
07452
07453 WN_INSERT_BlockLast( mp_master_block, Gen_Master(local_gtid));
07454
07455
07456 ST *return_st;
07457 WN_OFFSET return_ofst;
07458 PREG_NUM rreg1, rreg2;
07459 Create_Preg_or_Temp ( MTYPE_I4, IS_MASTER_PREG_NAME, &return_st, &return_ofst );
07460 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
07461 wn = WN_Stid ( MTYPE_I4, return_ofst, return_st, ST_type(return_st),
07462 WN_LdidPreg ( MTYPE_I4, rreg1 ));
07463 WN_linenum(wn) = line_number;
07464 WN_INSERT_BlockLast( mp_master_block, wn );
07465
07466
07467 WN *test = WN_EQ(MTYPE_I4,
07468 Gen_MP_Load( return_st, return_ofst ),
07469 WN_CreateIntconst ( OPC_I4INTCONST, 1));
07470 WN *if_wn = WN_CreateIf(test,WN_CreateBlock(),WN_CreateBlock());
07471 WN_linenum( if_wn ) = line_number;
07472
07473
07474 WN_INSERT_BlockLast( WN_then( if_wn ), master_block );
07475 WN_INSERT_BlockLast( mp_master_block, if_wn );
07476
07477
07478 #ifndef KEY
07479 WN_INSERT_BlockLast( mp_master_block, Gen_End_Master(local_gtid));
07480 #endif
07481
07482 return mp_master_block;
07483 }
07484
07485
07486
07487
07488
07489
07490
07491 extern WN *
07492 Gen_OMP_Begin_SPR (MP_process_type mpt)
07493 {
07494
07495
07496 WN *return_block = WN_CreateBlock();
07497 WN *store_gtid;
07498
07499 store_gtid = Gen_Store_Gtid();
07500 WN_INSERT_BlockLast(return_block, store_gtid );
07501 WN_INSERT_BlockLast(return_block, Gen_Serialized_Parallel(local_gtid));
07502
07503 return return_block;
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522
07523
07524
07525 }
07526
07527
07528
07529
07530 extern WN *
07531 Gen_OMP_End_SPR (MP_process_type mpt)
07532 {
07533
07534 WN *return_block = WN_CreateBlock();
07535 WN *store_gtid;
07536
07537 store_gtid = Gen_Store_Gtid();
07538 WN_INSERT_BlockLast(return_block, store_gtid );
07539 WN_INSERT_BlockLast(return_block,
07540 Gen_End_Serialized_Parallel(local_gtid));
07541
07542 return return_block;
07543
07544
07545
07546
07547
07548
07549
07550
07551
07552
07553
07554
07555
07556
07557
07558
07559
07560
07561
07562
07563
07564 }
07565
07566 static struct namelock_kind {
07567 ST *name;
07568 ST *lock;
07569 } *namelock_list = NULL;
07570
07571 static INT32 nl_idx = 0;
07572 static INT32 nl_max = 0;
07573
07574
07575
07576
07577
07578
07579
07580 static ST*
07581 NameLock_Find (ST *name) {
07582 INT32 i;
07583 for (i=0; i<nl_idx; i++) {
07584
07585
07586 {
07587 FmtAssert (ST_class(name) == CLASS_CONST, ("non-CONST class"));
07588 FmtAssert (ST_class(namelock_list[i].name) == CLASS_CONST,
07589 ("non-CONST class"));
07590
07591 TCON &name_tcon = Tcon_Table[ST_tcon(name)];
07592 TCON &list_tcon = Tcon_Table[ST_tcon(namelock_list[i].name)];
07593 if (Targ_String_Length(name_tcon) == Targ_String_Length(list_tcon) &&
07594 strncmp(Targ_String_Address(name_tcon),
07595 Targ_String_Address(list_tcon),
07596 Targ_String_Length(name_tcon)) == 0)
07597 return (namelock_list[i].lock);
07598 }
07599 }
07600 return NULL;
07601 }
07602
07603
07604
07605
07606
07607
07608
07609 static void
07610 NameLock_Add (ST *name, ST *lock) {
07611 FmtAssert (NameLock_Find(name) == NULL,
07612 ("NameLock_Add called with duplicate entry"));
07613
07614 if (nl_idx == nl_max) {
07615
07616 namelock_list = (struct namelock_kind*)
07617 MEM_POOL_Realloc (Malloc_Mem_Pool,
07618 namelock_list,
07619 nl_max*sizeof(struct namelock_kind),
07620 (nl_max+20)*sizeof(struct namelock_kind));
07621 nl_max += 20;
07622 }
07623 namelock_list[nl_idx].name = name;
07624 namelock_list[nl_idx].lock = lock;
07625 nl_idx++;
07626 }
07627
07628
07629
07630
07631
07632
07633
07634 static ST *
07635 Get_NameLock_ST (ST *name) {
07636 ST *lock_st;
07637
07638 if (name == NULL) return NULL;
07639
07640 lock_st = NameLock_Find (name);
07641 if (lock_st != NULL)
07642 {
07643 critical_lock_not_init = FALSE;
07644 return lock_st;
07645 }
07646
07647 lock_st = Create_Name_Lock (name);
07648 NameLock_Add (name, lock_st);
07649 return lock_st;
07650 }
07651
07652
07653
07654
07655
07656 static BOOL
07657 Is_NameLock_ST(ST *st)
07658 {
07659 if (ST_name(st)[0] != '_')
07660 return FALSE;
07661 return (strncmp(ST_name(st), "__namelock_", 11) == 0);
07662 }
07663
07664
07665
07666
07667
07668
07669
07670
07671
07672 static void
07673 Delayed_MP_Translation( WN * tree )
07674 {
07675 INT32 kidno;
07676 WN *kid;
07677 WN *next_kid;
07678
07679 ST *lock_st;
07680 WN *new_kid;
07681 ST *lock_stack[128];
07682 INT32 lptr = 0;
07683 INT32 pcf_nest = 0;
07684
07685 if (tree == NULL)
07686 return;
07687
07688 if (WN_opcode(tree) == OPC_BLOCK) {
07689 for (kid = WN_first(tree); kid; kid = next_kid) {
07690 next_kid = WN_next(kid);
07691 if (((WN_opcode(kid) == OPC_PRAGMA) ||
07692 (WN_opcode(kid) == OPC_XPRAGMA)) &&
07693 (WN_pragmas[WN_pragma(kid)].users & PUSER_MP)) {
07694 if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
07695
07696
07697
07698
07699 ++pcf_nest;
07700 if (WN_opcode(kid) == OPC_PRAGMA &&
07701 WN_pragma_omp(kid) &&
07702 WN_st(kid)) {
07703 lock_st = Get_NameLock_ST(WN_st(kid));
07704 }
07705 else if ((WN_opcode(kid) == OPC_XPRAGMA) &&
07706 (WN_operator(WN_kid0(kid)) == OPR_LDA))
07707 lock_st = WN_st(WN_kid0(kid));
07708 else if ((WN_opcode(kid) == OPC_PRAGMA) && WN_st(kid))
07709 lock_st = WN_st(kid);
07710 else{
07711 lock_st = NULL;
07712 Create_Unnamed_Critical_Lock( );
07713 }
07714 lock_stack[lptr++] = lock_st;
07715 if(lock_st){
07716 Linenum_Pusher p(WN_Get_Linenum(kid));
07717 new_kid = Gen_Critical( local_gtid, lock_st );
07718 } else {
07719 Linenum_Pusher p(WN_Get_Linenum(kid));
07720 new_kid = Gen_Critical( local_gtid, unnamed_lock_st );
07721 }
07722 if (WN_prev(kid))
07723 WN_next(WN_prev(kid)) = new_kid;
07724 else
07725 WN_first(tree) = new_kid;
07726 WN_prev(new_kid) = WN_prev(kid);
07727 WN_next(new_kid) = WN_next(kid);
07728 if (WN_next(kid))
07729 WN_prev(WN_next(kid)) = new_kid;
07730 else
07731 WN_last(tree) = new_kid;
07732 WN_DELETE_Tree ( kid );
07733 } else if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_END) {
07734
07735 --pcf_nest;
07736 lock_st = lock_stack[--lptr];
07737 if (WN_pragma_omp(kid) && WN_st(kid)) {
07738 FmtAssert (lock_st == Get_NameLock_ST(WN_st(kid)),
07739 ("Mismatch in lock on critical section"));
07740 }
07741 if (lock_st) {
07742 Linenum_Pusher p(WN_Get_Linenum(kid));
07743 new_kid = Gen_End_Critical (local_gtid, lock_st);
07744 } else {
07745 Linenum_Pusher p(WN_Get_Linenum(kid));
07746 new_kid = Gen_End_Critical (local_gtid, unnamed_lock_st);
07747 }
07748 if (WN_prev(kid))
07749 WN_next(WN_prev(kid)) = new_kid;
07750 else
07751 WN_first(tree) = new_kid;
07752 WN_prev(new_kid) = WN_prev(kid);
07753 WN_next(new_kid) = WN_next(kid);
07754 if (WN_next(kid))
07755 WN_prev(WN_next(kid)) = new_kid;
07756 else
07757 WN_last(tree) = new_kid;
07758 WN_Delete ( kid );
07759 }else if (WN_pragma(kid) == WN_PRAGMA_ORDERED_BEGIN ||
07760 WN_pragma(kid) == WN_PRAGMA_ORDERED_END) {
07761
07762 WN *call;
07763 call = ( WN_pragma( kid ) == WN_PRAGMA_ORDERED_BEGIN?
07764 Gen_Ordered(local_gtid):
07765 Gen_End_Ordered(local_gtid));
07766 WN_INSERT_BlockAfter (tree, kid, call);
07767 WN_Delete (WN_EXTRACT_FromBlock (tree, kid));
07768 }
07769 } else if ( WN_opcode(kid) == OPC_REGION) {
07770 Delayed_MP_Translation( WN_region_body(kid));
07771 } else {
07772 Delayed_MP_Translation( kid );
07773 }
07774 }
07775 } else {
07776 for (kidno = 0; kidno < WN_kid_count(tree); kidno++)
07777 if (WN_kid(tree, kidno))
07778 Delayed_MP_Translation( WN_kid(tree, kidno));
07779 }
07780 }
07781
07782
07783
07784
07785
07786
07787
07788
07789
07790 static void
07791 Strip_Nested_MP ( WN * tree, BOOL pcf_ok )
07792 {
07793 INT32 kidno;
07794 ST *lock_st;
07795 WN *new_kid;
07796 WN *kid;
07797 WN *next_kid;
07798 ST *lock_stack[128];
07799 INT32 lptr = 0;
07800 INT32 pcf_nest = 0;
07801
07802 if (tree == NULL)
07803 return;
07804
07805 if (WN_opcode(tree) == OPC_BLOCK) {
07806 for (kid = WN_first(tree); kid; kid = next_kid) {
07807 next_kid = WN_next(kid);
07808 if (((WN_opcode(kid) == OPC_PRAGMA) ||
07809 (WN_opcode(kid) == OPC_XPRAGMA)) &&
07810 (WN_pragmas[WN_pragma(kid)].users & PUSER_MP)) {
07811 if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
07812
07813
07814
07815 } else if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_END) {
07816
07817
07818
07819 } else if ((WN_pragma(kid) == WN_PRAGMA_BARRIER) &&
07820 (pcf_nest == 0) && pcf_ok) {
07821
07822 } else if ((WN_pragma(kid) == WN_PRAGMA_ENTER_GATE) &&
07823 (pcf_nest == 0) && pcf_ok) {
07824
07825 } else if ((WN_pragma(kid) == WN_PRAGMA_EXIT_GATE) &&
07826 (pcf_nest == 0) && pcf_ok) {
07827
07828 } else if ((WN_pragma(kid) == WN_PRAGMA_INDEPENDENT_BEGIN) &&
07829 (pcf_nest++ == 0) && pcf_ok) {
07830
07831 } else if ((WN_pragma(kid) == WN_PRAGMA_INDEPENDENT_END) &&
07832 (--pcf_nest == 0) && pcf_ok) {
07833
07834
07835
07836 } else if ((WN_pragma(kid) == WN_PRAGMA_SINGLE_PROCESS_BEGIN) &&
07837 (pcf_nest++ == 0) && pcf_ok) {
07838
07839
07840 } else if ((WN_pragma(kid) == WN_PRAGMA_SINGLE_PROCESS_END) &&
07841 (--pcf_nest == 0) && pcf_ok) {
07842
07843
07844 } else if ((WN_pragma(kid) == WN_PRAGMA_MASTER_BEGIN) &&
07845 (pcf_nest == 0) && pcf_ok ) {
07846
07847
07848 } else if (WN_pragma(kid) == WN_PRAGMA_ORDERED_BEGIN ||
07849 WN_pragma(kid) == WN_PRAGMA_ORDERED_END) {
07850
07851
07852
07853 } else {
07854
07855 if (WN_prev(kid))
07856 WN_next(WN_prev(kid)) = WN_next(kid);
07857 else
07858 WN_first(tree) = WN_next(kid);
07859 if (WN_next(kid))
07860 WN_prev(WN_next(kid)) = WN_prev(kid);
07861 else
07862 WN_last(tree) = WN_prev(kid);
07863 WN_DELETE_Tree ( kid );
07864 }
07865 } else if ((WN_opcode(kid) == OPC_REGION) &&
07866 WN_first(WN_region_pragmas(kid)) &&
07867 (WN_pragmas[WN_pragma(WN_first(WN_region_pragmas(kid)))].users
07868 & PUSER_MP)) {
07869 WN_PRAGMA_ID region_type = (WN_PRAGMA_ID)
07870 WN_pragma(WN_first(WN_region_pragmas(kid)));
07871
07872 if ((region_type == WN_PRAGMA_SINGLE_PROCESS_BEGIN ||
07873 region_type == WN_PRAGMA_PDO_BEGIN ||
07874 #ifdef KEY
07875 region_type == WN_PRAGMA_PWORKSHARE_BEGIN ||
07876 #endif
07877 region_type == WN_PRAGMA_MASTER_BEGIN) &&
07878 (pcf_nest == 0) && pcf_ok) {
07879
07880
07881
07882 #ifdef KEY
07883 if (region_type != WN_PRAGMA_PWORKSHARE_BEGIN)
07884 #endif
07885 Strip_Nested_MP ( WN_region_body(kid), FALSE );
07886 } else {
07887 if (region_type == WN_PRAGMA_PDO_BEGIN)
07888 Move_Non_POD_Finalization_Code(WN_region_body(kid));
07889
07890
07891
07892 if (WN_first(WN_region_body(kid))) {
07893 if (WN_pragma_omp(WN_first(WN_region_pragmas(kid))) &&
07894 (region_type == WN_PRAGMA_DOACROSS ||
07895 region_type == WN_PRAGMA_PARALLEL_DO ||
07896 #ifdef KEY
07897 region_type == WN_PRAGMA_PARALLEL_WORKSHARE ||
07898 #endif
07899 region_type == WN_PRAGMA_PARALLEL_BEGIN)) {
07900 #ifdef KEY
07901 MP_process_type nested_mpt =
07902 (region_type == (WN_PRAGMA_PARALLEL_BEGIN ||
07903 WN_PRAGMA_PARALLEL_WORKSHARE) ?
07904 MPP_PARALLEL_REGION : MPP_PARALLEL_DO);
07905 #else
07906 MP_process_type nested_mpt =
07907 (region_type == WN_PRAGMA_PARALLEL_BEGIN ?
07908 MPP_PARALLEL_REGION : MPP_PARALLEL_DO);
07909 #endif
07910
07911
07912
07913
07914
07915
07916
07917 #ifndef KEY
07918 WN_INSERT_BlockFirst(WN_region_body(kid),
07919 Gen_Serialized_Parallel( local_gtid ));
07920 WN_INSERT_BlockLast(WN_region_body(kid),
07921 Gen_End_Serialized_Parallel( local_gtid ));
07922 #endif
07923 }
07924
07925 if (WN_prev(kid))
07926 WN_next(WN_prev(kid)) = next_kid = WN_first(WN_region_body(kid));
07927 else
07928 WN_first(tree) = next_kid = WN_first(WN_region_body(kid));
07929 WN_prev(WN_first(WN_region_body(kid))) = WN_prev(kid);
07930 WN_next(WN_last(WN_region_body(kid))) = WN_next(kid);
07931 if (WN_next(kid))
07932 WN_prev(WN_next(kid)) = WN_last(WN_region_body(kid));
07933 else
07934 WN_last(tree) = WN_last(WN_region_body(kid));
07935 } else {
07936 if (WN_prev(kid))
07937 WN_next(WN_prev(kid)) = next_kid = WN_next(kid);
07938 else
07939 WN_first(tree) = next_kid = WN_next(kid);
07940 if (WN_next(kid))
07941 WN_prev(WN_next(kid)) = WN_prev(kid);
07942 else
07943 WN_last(tree) = WN_prev(kid);
07944 }
07945 WN_DELETE_Tree ( WN_region_pragmas(kid) );
07946 WN_DELETE_Tree ( WN_region_exits(kid) );
07947 WN_Delete ( WN_region_body(kid) );
07948 RID_Delete ( Current_Map_Tab, kid );
07949 WN_Delete ( kid );
07950
07951 }
07952
07953
07954 } else if (WN_opcode(kid) == OPC_IF && WN_Is_If_MpVersion(kid)) {
07955
07956
07957
07958
07959 if (TRUE ||
07960 inside_versioning_if) {
07961
07962
07963
07964
07965
07966
07967
07968
07969
07970 Strip_Nested_MP ( WN_then(kid) , ((pcf_nest == 0) && pcf_ok) );
07971 Strip_Nested_MP ( WN_else(kid) , ((pcf_nest == 0) && pcf_ok) );
07972 WN_DELETE_Tree(WN_if_test(kid));
07973 WN_if_test(kid) = WN_CreateIntconst(OPC_I4INTCONST, 0);
07974 WN_Reset_If_MpVersion(kid);
07975
07976 } else {
07977 BOOL old_ivi = inside_versioning_if;
07978
07979 inside_versioning_if = TRUE;
07980 Strip_Nested_MP ( WN_then(kid) , ((pcf_nest == 0) && pcf_ok) );
07981 Strip_Nested_MP ( WN_else(kid) , ((pcf_nest == 0) && pcf_ok) );
07982 inside_versioning_if = old_ivi;
07983 }
07984
07985 } else {
07986
07987 Strip_Nested_MP ( kid, ((pcf_nest == 0) && pcf_ok) );
07988 }
07989 }
07990
07991 } else {
07992
07993 for (kidno = 0; kidno < WN_kid_count(tree); kidno++)
07994 if (WN_kid(tree, kidno))
07995 Strip_Nested_MP ( WN_kid(tree, kidno), ((pcf_nest == 0) && pcf_ok) );
07996
07997 }
07998 }
07999
08000
08001
08002
08003
08004
08005
08006
08007 static void
08008 Process_Preamble_Stores ( WN * tree, VAR_TABLE * vtab )
08009 {
08010 OPCODE op;
08011 OPERATOR opr;
08012 INT32 i;
08013 WN *r;
08014 ST *old_sym;
08015 WN_OFFSET old_offset;
08016 VAR_TABLE *w;
08017
08018
08019
08020 if (tree == NULL)
08021 return;
08022
08023
08024
08025 op = WN_opcode(tree);
08026 opr = OPCODE_operator(op);
08027
08028
08029
08030 if (OPCODE_has_sym(op) && WN_st(tree) &&
08031 (ST_class(WN_st(tree)) != CLASS_PREG)) {
08032 if (opr == OPR_STID) {
08033 old_sym = WN_st(tree);
08034 old_offset = WN_offsetx(tree);
08035 for (w=vtab; w->orig_st; w++) {
08036 if ((w->vtree == NULL) &&
08037 (w->orig_st == old_sym) &&
08038 (w->has_offset ? (w->orig_offset == old_offset) : TRUE )) {
08039 if (copyin_block == NULL)
08040 copyin_block = WN_CreateBlock ( );
08041 WN_INSERT_BlockLast ( copyin_block,
08042 Gen_MP_Load_Store ( w->orig_st, old_offset,
08043 w->new_st, old_offset,
08044 w->is_dynamic_array ));
08045 break;
08046 }
08047 }
08048 } else if (opr == OPR_ISTORE) {
08049 for (w=vtab; w->orig_st; w++) {
08050 if ((w->vtree && (WN_Compare_Trees(w->vtree, WN_kid1(tree)) == 0)) ||
08051 (w->vtreex && (WN_Compare_Trees(w->vtreex, WN_kid1(tree)) == 0))) {
08052 if (copyin_block == NULL)
08053 copyin_block = WN_CreateBlock ( );
08054 WN_INSERT_BlockLast ( copyin_block,
08055 Gen_MP_Load_Store ( w->orig_st, w->orig_offset,
08056 w->new_st, w->new_offset,
08057 w->is_dynamic_array ));
08058 break;
08059 }
08060 }
08061 }
08062 }
08063
08064
08065
08066 if (op == OPC_BLOCK)
08067 for (r = WN_first(tree); r; r = WN_next(r))
08068 Process_Preamble_Stores ( r, vtab );
08069 else
08070 for (i=0; i < WN_kid_count(tree); i++)
08071 Process_Preamble_Stores ( WN_kid(tree, i), vtab );
08072
08073 return;
08074 }
08075
08076
08077
08078
08079
08080
08081
08082
08083
08084
08085
08086 static void
08087 Cleanup_Ordered (WN* block_wn, WN* wn) {
08088
08089 OPCODE opc;
08090
08091 if (!wn) return;
08092
08093 opc = WN_opcode(wn);
08094 if (opc == OPC_VCALL) {
08095 char* name = ST_name(WN_st(wn));
08096 #ifdef KEY
08097 if (strcmp (name, "__ompc_ordered") == 0 ||
08098 strcmp (name, "__ompc_end_ordered") == 0 ) {
08099 #else
08100 if (strcmp (name, "__omp_ordered") == 0 ||
08101 strcmp (name, "__omp_end_ordered") ==0 ||
08102 strcmp (name, "__omp_pdo_ordered_begin_iter") == 0 ||
08103 strcmp (name, "__omp_pdo_ordered_end_iter") == 0 ||
08104 strcmp (name, "__omp_begin_ordered") == 0 ||
08105 strcmp (name, "__omp_end_ordered") == 0 ) {
08106 #endif
08107 WN_DELETE_Tree(WN_EXTRACT_FromBlock (block_wn, wn));
08108 return;
08109 }
08110 }
08111
08112 if (opc == OPC_REGION && RID_TYPE_mp(REGION_get_rid(wn))) {
08113
08114
08115
08116
08117
08118 WN* pragma = WN_first(WN_region_pragmas(wn));
08119 while (pragma) {
08120 if (WN_pragma(pragma) == WN_PRAGMA_PARALLEL_BEGIN ||
08121 #ifdef KEY
08122 WN_pragma(pragma) == WN_PRAGMA_PARALLEL_WORKSHARE ||
08123 #endif
08124 WN_pragma(pragma) == WN_PRAGMA_PARALLEL_DO) {
08125 return;
08126 }
08127 pragma = WN_next(pragma);
08128 }
08129 }
08130
08131 if (opc == OPC_BLOCK) {
08132 WN* kid = WN_first(wn);
08133 while (kid) {
08134
08135 WN* tmp = WN_next(kid);
08136 Cleanup_Ordered (wn, kid);
08137 kid = tmp;
08138 }
08139 }
08140 else {
08141 INT i;
08142 for (i=0; i<WN_kid_count(wn); i++) {
08143 Cleanup_Ordered (block_wn, WN_kid(wn,i));
08144 }
08145 }
08146 }
08147
08148
08149
08150
08151
08152
08153
08154
08155 typedef HASH_TABLE<VINDEX16,VINDEX16> VV_HASH_TABLE;
08156 typedef STACK<VINDEX16> V_STACK;
08157 static MEM_POOL MP_Dep_Pool;
08158 static BOOL mp_dep_pool_initialized;
08159 void Create_Vertices(WN *wn, VV_HASH_TABLE *parent_to_child,
08160 V_STACK *parent_vertices,
08161 ARRAY_DIRECTED_GRAPH16 *parent_graph,
08162 ARRAY_DIRECTED_GRAPH16 *child_graph);
08163
08164
08165 void
08166 MP_Fix_Dependence_Graph(PU_Info *parent_pu_info,
08167 PU_Info *child_pu_info, WN *child_wn)
08168 {
08169 ARRAY_DIRECTED_GRAPH16 *parent_graph =
08170 (ARRAY_DIRECTED_GRAPH16 *) PU_Info_depgraph_ptr(parent_pu_info);
08171 if (!parent_graph) {
08172 Set_PU_Info_depgraph_ptr(child_pu_info,NULL);
08173 return;
08174 }
08175 if (!mp_dep_pool_initialized) {
08176 MEM_POOL_Initialize(&MP_Dep_Pool,"MP_Dep_Pool",FALSE);
08177 mp_dep_pool_initialized = TRUE;
08178 }
08179 MEM_POOL_Push(&MP_Dep_Pool);
08180
08181
08182 ARRAY_DIRECTED_GRAPH16 *child_graph =
08183 CXX_NEW(ARRAY_DIRECTED_GRAPH16(100, 500,
08184 WN_MAP_DEPGRAPH, DEP_ARRAY_GRAPH), Malloc_Mem_Pool);
08185 Set_PU_Info_depgraph_ptr(child_pu_info,child_graph);
08186 Set_PU_Info_state(child_pu_info,WT_DEPGRAPH,Subsect_InMem);
08187
08188
08189
08190 VV_HASH_TABLE *parent_to_child =
08191 CXX_NEW(VV_HASH_TABLE(200,&MP_Dep_Pool),&MP_Dep_Pool);
08192
08193 V_STACK *parent_vertices = CXX_NEW(V_STACK(&MP_Dep_Pool),&MP_Dep_Pool);
08194 Create_Vertices(child_wn,parent_to_child,parent_vertices,parent_graph,
08195 child_graph);
08196
08197
08198 INT i;
08199 for (i=0; i<parent_vertices->Elements(); i++) {
08200 VINDEX16 parent_v = parent_vertices->Bottom_nth(i);
08201 VINDEX16 child_v = parent_to_child->Find(parent_v);
08202 Is_True(child_v,("child_v missing "));
08203 EINDEX16 e;
08204 while (e = parent_graph->Get_Out_Edge(parent_v)) {
08205 VINDEX16 parent_sink = parent_graph->Get_Sink(e);
08206 VINDEX16 child_sink = parent_to_child->Find(parent_sink);
08207 Is_True(child_sink,("child_sink missing "));
08208 child_graph->Add_Edge(child_v,child_sink,
08209 parent_graph->Dep(e),parent_graph->Is_Must(e));
08210
08211 parent_graph->Remove_Edge(e);
08212 }
08213 }
08214 for (i=0; i<parent_vertices->Elements(); i++) {
08215
08216
08217 VINDEX16 parent_v = parent_vertices->Bottom_nth(i);
08218 VINDEX16 child_v = parent_to_child->Find(parent_v);
08219 WN *wn = parent_graph->Get_Wn(parent_v);
08220 parent_graph->Delete_Vertex(parent_v);
08221 child_graph->Set_Wn(child_v,wn);
08222 }
08223 CXX_DELETE(parent_to_child,&MP_Dep_Pool);
08224 CXX_DELETE(parent_vertices,&MP_Dep_Pool);
08225 MEM_POOL_Pop(&MP_Dep_Pool);
08226 }
08227
08228
08229
08230 void
08231 Create_Vertices(WN *wn, VV_HASH_TABLE *parent_to_child,
08232 V_STACK *parent_vertices,
08233 ARRAY_DIRECTED_GRAPH16 *parent_graph,
08234 ARRAY_DIRECTED_GRAPH16 *child_graph)
08235 {
08236 OPCODE opcode = WN_opcode(wn);
08237 if (opcode == OPC_BLOCK) {
08238 WN *kid = WN_first (wn);
08239 while (kid) {
08240 Create_Vertices(kid,parent_to_child,parent_vertices,parent_graph,
08241 child_graph);
08242 kid = WN_next(kid);
08243 }
08244 return;
08245 }
08246 if (OPCODE_is_load(opcode) || OPCODE_is_store(opcode)
08247 || OPCODE_is_call(opcode)) {
08248 VINDEX16 parent_v = parent_graph->Get_Vertex(wn);
08249 if (parent_v) {
08250
08251
08252 VINDEX16 child_v = child_graph->Add_Vertex(wn);
08253 parent_to_child->Enter(parent_v,child_v);
08254 parent_vertices->Push(parent_v);
08255 }
08256 }
08257 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
08258 Create_Vertices(WN_kid(wn,kidno),parent_to_child,parent_vertices,
08259 parent_graph,child_graph);
08260 }
08261 }
08262
08263
08264
08265
08266
08267
08268
08269
08270
08271
08272
08273
08274
08275
08276
08277
08278
08279
08280
08281
08282
08283
08284
08285
08286
08287
08288
08289
08290
08291
08292
08293
08294
08295
08296
08297
08298 static WN *Find_Non_POD_Finalization_Code(WN *wn, WN **final_if_parent);
08299 static void Move_Non_POD_Finalization_Code_Rec(WN *wn);
08300 static void Find_And_Move_Finalization_Code(WN *parent, WN *do_wn);
08301
08302 void
08303 Move_Non_POD_Finalization_Code(WN *block)
08304 {
08305 Is_True(block && WN_operator(block) == OPR_BLOCK, ("bad block"));
08306 Move_Non_POD_Finalization_Code_Rec(block);
08307 }
08308
08309
08310 static void
08311 Move_Non_POD_Finalization_Code_Rec(WN *wn)
08312 {
08313 Is_True(wn, ("NULL wn"));
08314 Is_True(WN_operator(wn) != OPR_DO_LOOP, ("recursed into a DO loop"));
08315
08316 if (WN_operator(wn) == OPR_BLOCK) {
08317 for (WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
08318 if (WN_operator(stmt) == OPR_DO_LOOP)
08319 Find_And_Move_Finalization_Code(wn, stmt);
08320 else
08321 Move_Non_POD_Finalization_Code_Rec(stmt);
08322 }
08323
08324 } else {
08325 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++)
08326 Move_Non_POD_Finalization_Code_Rec(WN_kid(wn, kidno));
08327 }
08328 }
08329
08330 static void
08331 Find_And_Move_Finalization_Code(WN *parent, WN *do_wn)
08332 {
08333 Is_True(parent && WN_operator(parent) == OPR_BLOCK, ("bad parent"));
08334 Is_True(do_wn && WN_operator(do_wn) == OPR_DO_LOOP, ("bad do_wn"));
08335
08336 WN *final_if, *final_if_parent, *do_body = WN_do_body(do_wn);
08337
08338 final_if = Find_Non_POD_Finalization_Code(do_body, &final_if_parent);
08339
08340 if (!final_if)
08341 return;
08342
08343
08344 WN *bar1 = WN_prev(final_if), *bar2 = WN_next(final_if),
08345 *then = WN_then(final_if), *bar3 = WN_first(then),
08346 *bar4 = WN_last(then);
08347 Is_True(bar1 && WN_operator(bar1) == OPR_FORWARD_BARRIER,
08348 ("bad bar1"));
08349 Is_True(bar2 && WN_operator(bar2) == OPR_BACKWARD_BARRIER,
08350 ("bad bar2"));
08351 Is_True(bar3 && WN_operator(bar3) == OPR_BACKWARD_BARRIER,
08352 ("bad bar3"));
08353 Is_True(bar4 && WN_operator(bar4) == OPR_FORWARD_BARRIER,
08354 ("bad bar4"));
08355 WN_DELETE_FromBlock(final_if_parent, bar1);
08356 WN_DELETE_FromBlock(final_if_parent, bar2);
08357 WN_DELETE_FromBlock(then, bar3);
08358 WN_DELETE_FromBlock(then, bar4);
08359
08360
08361 WN_EXTRACT_FromBlock(final_if_parent, final_if);
08362 WN *final_code = WN_then(final_if);
08363 WN_then(final_if) = NULL;
08364 WN_DELETE_Tree(final_if);
08365 WN_INSERT_BlockAfter(parent, do_wn, final_code);
08366 }
08367
08368
08369 static WN *
08370 Find_Non_POD_Finalization_Code(WN *wn, WN **final_if_parent)
08371 {
08372 Is_True(wn, ("NULL wn"));
08373 if (WN_operator(wn) == OPR_BLOCK) {
08374
08375
08376 for (WN *stmt = WN_first(wn); stmt; stmt = WN_next(stmt)) {
08377 BOOL first_and_last;
08378 if (Is_Nonpod_Finalization_IF(stmt, &first_and_last)) {
08379 *final_if_parent = wn;
08380 return stmt;
08381 }
08382
08383 if (WN_operator(stmt) == OPR_REGION &&
08384 WN_first(WN_region_pragmas(stmt)) &&
08385 WN_pragma(WN_first(WN_region_pragmas(stmt))) == WN_PRAGMA_PDO_BEGIN)
08386 continue;
08387
08388
08389 WN *retval = Find_Non_POD_Finalization_Code(stmt, final_if_parent);
08390 if (retval)
08391 return retval;
08392 }
08393
08394 } else {
08395 for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
08396 WN *retval = Find_Non_POD_Finalization_Code(WN_kid(wn, kidno),
08397 final_if_parent);
08398 if (retval)
08399 return retval;
08400 }
08401 }
08402
08403 return NULL;
08404 }
08405
08406
08407
08408
08409
08410
08411
08412 static WN * Copy_Non_MP_Tree_Rec ( WN * tree , V_STACK *mp_vertices,
08413 VV_HASH_TABLE *mp_to_nonmp);
08414
08415 WN *
08416 Copy_Non_MP_Tree( WN * tree )
08417 {
08418 V_STACK *mp_vertices=0;
08419 VV_HASH_TABLE *mp_to_nonmp = 0;
08420 if (Current_Dep_Graph) {
08421 if (!mp_dep_pool_initialized) {
08422 MEM_POOL_Initialize(&MP_Dep_Pool,"MP_Dep_Pool",FALSE);
08423 mp_dep_pool_initialized = TRUE;
08424 }
08425 MEM_POOL_Push(&MP_Dep_Pool);
08426 mp_vertices = CXX_NEW(V_STACK(&MP_Dep_Pool),&MP_Dep_Pool);
08427 mp_to_nonmp = CXX_NEW(VV_HASH_TABLE(200,&MP_Dep_Pool),&MP_Dep_Pool);
08428 }
08429 WN *result = Copy_Non_MP_Tree_Rec(tree,mp_vertices,mp_to_nonmp);
08430
08431
08432 if (Current_Dep_Graph) {
08433 for (INT i=0; i<mp_vertices->Elements(); i++) {
08434 VINDEX16 mp_v = mp_vertices->Bottom_nth(i);
08435 VINDEX16 nonmp_v = mp_to_nonmp->Find(mp_v);
08436 Is_True(nonmp_v,("nonmp_v missing "));
08437 EINDEX16 e = Current_Dep_Graph->Get_Out_Edge(mp_v);
08438 while (e) {
08439 VINDEX16 mp_sink = Current_Dep_Graph->Get_Sink(e);
08440 VINDEX16 nonmp_sink = mp_to_nonmp->Find(mp_sink);
08441 Is_True(nonmp_sink,("nonmp_sink missing "));
08442 if ((nonmp_v != nonmp_sink) || !
08443 Current_Dep_Graph->Get_Edge(nonmp_v,nonmp_v)) {
08444 if (!Current_Dep_Graph->Add_Edge(nonmp_v,nonmp_sink,
08445 Current_Dep_Graph->Dep(e),Current_Dep_Graph->Is_Must(e))) {
08446 Current_Dep_Graph->Erase_Graph();
08447 Current_Dep_Graph = NULL;
08448 Set_PU_Info_depgraph_ptr(Current_PU_Info,Current_Dep_Graph);
08449 Set_PU_Info_state(Current_PU_Info,WT_DEPGRAPH,Subsect_InMem);
08450
08451 return result;
08452 }
08453 }
08454 e = Current_Dep_Graph->Get_Next_Out_Edge(e);
08455 }
08456 }
08457 }
08458 return result;
08459 }
08460
08461 static WN *
08462 Copy_Non_MP_Tree_Rec ( WN * tree , V_STACK *mp_vertices,
08463 VV_HASH_TABLE *mp_to_nonmp)
08464 {
08465 INT32 kidno;
08466 ST *lock_st;
08467 WN *new_wn;
08468 WN *kid;
08469 WN *prev_kid;
08470 WN *next_kid;
08471 WN *new_kid;
08472 #define STACK_CHUNK 10
08473 INT32 *spr_stack = NULL;
08474
08475
08476
08477
08478 WN **kid_stack = NULL;
08479 INT32 kptr = 0;
08480 INT32 kptr_max = 0;
08481 ST **lock_stack = NULL;
08482 INT32 lptr = 0;
08483 INT32 lptr_max = 0;
08484
08485
08486
08487 BOOL must_move_non_pod = FALSE;
08488
08489 if (tree == NULL)
08490 return (NULL);
08491
08492 #ifdef Is_True_On
08493 if (WN_opcode(tree) == OPC_REGION) {
08494 RID *rid = REGION_get_rid(tree);
08495 Is_True(rid != NULL, ("Copy_Non_MP_Tree_Rec, NULL rid"));
08496 }
08497 #endif
08498
08499 new_wn = WN_CopyNode (tree);
08500
08501 if (Current_Dep_Graph) {
08502 VINDEX16 mp_v = Current_Dep_Graph->Get_Vertex(tree);
08503 if (mp_v) {
08504 VINDEX16 nonmp_v = Current_Dep_Graph->Add_Vertex(new_wn);
08505 if (!nonmp_v) {
08506 Current_Dep_Graph->Erase_Graph();
08507 Current_Dep_Graph = NULL;
08508 } else {
08509 mp_vertices->Push(mp_v);
08510 mp_to_nonmp->Enter(mp_v,nonmp_v);
08511 }
08512 }
08513 }
08514
08515 if (WN_opcode(tree) == OPC_BLOCK) {
08516
08517 prev_kid = new_kid = NULL;
08518 for (kid = WN_first(tree); kid; kid = next_kid) {
08519 next_kid = WN_next(kid);
08520 if (((WN_opcode(kid) == OPC_PRAGMA) ||
08521 (WN_opcode(kid) == OPC_XPRAGMA)) &&
08522 (WN_pragmas[WN_pragma(kid)].users & PUSER_MP)) {
08523
08524
08525 if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
08526 if ((WN_opcode(kid) == OPC_XPRAGMA) &&
08527 (WN_operator(WN_kid0(kid)) == OPR_LDA))
08528
08529 #ifdef KEY
08530 lock_st = Get_NameLock_ST( WN_st(WN_kid0(kid)) );
08531 #else
08532 lock_st = WN_st(WN_kid0(kid));
08533 #endif
08534 else if ((WN_opcode(kid) == OPC_PRAGMA) && WN_st(kid))
08535
08536 #ifdef KEY
08537 lock_st = Get_NameLock_ST( WN_st(kid) );
08538 #else
08539 lock_st = WN_st(kid);
08540 #endif
08541 else{
08542 lock_st = NULL;
08543 Create_Unnamed_Critical_Lock( );
08544 }
08545 if (lptr == lptr_max) {
08546 lock_stack = (ST**) MEM_POOL_Realloc (Malloc_Mem_Pool, lock_stack,
08547 sizeof(ST*)*lptr_max,
08548 sizeof(ST*)*(lptr_max+STACK_CHUNK));
08549 lptr_max += STACK_CHUNK;
08550 }
08551 lock_stack[lptr++] = lock_st;
08552 Create_Gtid_ST( );
08553 if (lock_st)
08554 new_kid = Gen_Critical( local_gtid, lock_st );
08555 else
08556 new_kid = Gen_Critical( local_gtid, unnamed_lock_st );
08557 WN_prev(new_kid) = prev_kid;
08558 if (prev_kid)
08559 WN_next(prev_kid) = new_kid;
08560 else
08561 WN_first(new_wn) = new_kid;
08562 prev_kid = new_kid;
08563 } else if (WN_pragma(kid) == WN_PRAGMA_CRITICAL_SECTION_END) {
08564 lock_st = lock_stack[--lptr];
08565 if (lock_st)
08566 new_kid = Gen_End_Critical(local_gtid, lock_st);
08567 else
08568 new_kid = Gen_End_Critical(local_gtid, unnamed_lock_st);
08569 WN_prev(new_kid) = prev_kid;
08570 if (prev_kid)
08571 WN_next(prev_kid) = new_kid;
08572 else
08573 WN_first(new_wn) = new_kid;
08574 prev_kid = new_kid;
08575 }
08576 }
08577 else if ((WN_opcode(kid) == OPC_REGION) &&
08578 WN_first(WN_region_pragmas(kid)) &&
08579 (WN_pragmas[WN_pragma(WN_first(WN_region_pragmas(kid)))].users
08580 & PUSER_MP)) {
08581
08582 WN_PRAGMA_ID pragma =
08583 (WN_PRAGMA_ID) WN_pragma(WN_first(WN_region_pragmas(kid)));
08584 if (kptr == kptr_max) {
08585 kid_stack = (WN**) MEM_POOL_Realloc (Malloc_Mem_Pool, kid_stack,
08586 sizeof(WN*) * kptr_max,
08587 sizeof(WN*) * (kptr_max+STACK_CHUNK));
08588 spr_stack = (INT32*) MEM_POOL_Realloc (Malloc_Mem_Pool, spr_stack,
08589 sizeof(INT32)*kptr_max,
08590 sizeof(INT32)*(kptr_max+STACK_CHUNK));
08591 kptr_max += STACK_CHUNK;
08592 }
08593
08594 spr_stack[kptr] = 0;
08595 if (WN_pragma_omp(WN_first(WN_region_pragmas(kid))) &&
08596 (pragma == WN_PRAGMA_DOACROSS ||
08597 pragma == WN_PRAGMA_PARALLEL_DO ||
08598 pragma == WN_PRAGMA_PARALLEL_WORKSHARE ||
08599 pragma == WN_PRAGMA_PARALLEL_BEGIN)) {
08600 #ifdef KEY
08601 MP_process_type mpt = ((pragma == WN_PRAGMA_PARALLEL_BEGIN ||
08602 pragma == WN_PRAGMA_PARALLEL_WORKSHARE) ?
08603 MPP_PARALLEL_REGION :
08604 MPP_PARALLEL_DO);
08605 #else
08606 MP_process_type mpt = (pragma == WN_PRAGMA_PARALLEL_BEGIN ?
08607 MPP_PARALLEL_REGION :
08608 MPP_PARALLEL_DO);
08609 #endif
08610 new_kid = Gen_OMP_Begin_SPR(mpt);
08611 WN_prev(new_kid) = prev_kid;
08612 if (prev_kid)
08613 WN_next(prev_kid) = new_kid;
08614 else
08615 WN_first(new_wn) = new_kid;
08616 prev_kid = new_kid;
08617 spr_stack[kptr] = (mpt == MPP_PARALLEL_REGION ? 1 : 2);
08618 } else if (WN_pragma_omp(WN_first(WN_region_pragmas(kid))) &&
08619 pragma == WN_PRAGMA_PDO_BEGIN) {
08620 must_move_non_pod = TRUE;
08621 }
08622
08623 kid_stack[kptr++] = next_kid;
08624 next_kid = WN_first(WN_region_body(kid));
08625 } else {
08626
08627 new_kid = Copy_Non_MP_Tree_Rec ( kid, mp_vertices,mp_to_nonmp );
08628 WN_prev(new_kid) = prev_kid;
08629 if (prev_kid)
08630 WN_next(prev_kid) = new_kid;
08631 else
08632 WN_first(new_wn) = new_kid;
08633 prev_kid = new_kid;
08634
08635
08636 if (WN_opcode(kid) == OPC_REGION) {
08637 RID *rid = REGION_get_rid(kid);
08638 if (!RID_TYPE_mp(rid)) {
08639
08640
08641 mUINT32 new_region_id = WN_region_id(new_kid);
08642 mUINT32 old_region_id = WN_region_id(kid);
08643
08644 WN_set_region_id(new_kid, WN_region_id(kid));
08645 REGION_new_wn(new_kid, kid);
08646 WN_set_region_id(kid, New_Region_Id());
08647 REGION_clone(new_kid, kid, NULL);
08648 }
08649
08650 }
08651 }
08652 if ((next_kid == NULL) && kptr) {
08653 if (spr_stack[kptr-1] != 0) {
08654
08655 new_kid = Gen_OMP_End_SPR(spr_stack[kptr-1] == 1?
08656 MPP_PARALLEL_REGION :
08657 MPP_PARALLEL_DO);
08658 WN_prev(new_kid) = prev_kid;
08659 if (prev_kid)
08660 WN_next(prev_kid) = new_kid;
08661 else
08662 WN_first(new_wn) = new_kid;
08663 prev_kid = new_kid;
08664 }
08665
08666 next_kid = kid_stack[--kptr];
08667 #ifdef KEY
08668
08669 while (!next_kid && kptr)
08670 next_kid = kid_stack[--kptr];
08671 #endif // KEY
08672 }
08673
08674 }
08675
08676 if (new_kid)
08677 WN_next(new_kid) = NULL;
08678 else
08679 WN_first(new_wn) = NULL;
08680 WN_last(new_wn) = new_kid;
08681
08682 if (must_move_non_pod)
08683 Move_Non_POD_Finalization_Code(new_wn);
08684
08685 }
08686 else {
08687
08688 for (kidno = 0; kidno < WN_kid_count(tree); kidno++) {
08689 kid = WN_kid(tree, kidno);
08690 if (kid)
08691 WN_kid(new_wn, kidno) = Copy_Non_MP_Tree_Rec ( kid, mp_vertices,
08692 mp_to_nonmp );
08693 else
08694 WN_kid(new_wn, kidno) = NULL;
08695 }
08696
08697 }
08698
08699 if (lock_stack) MEM_POOL_FREE (Malloc_Mem_Pool, lock_stack);
08700 if (kid_stack) MEM_POOL_FREE (Malloc_Mem_Pool, kid_stack);
08701 if (spr_stack) MEM_POOL_FREE (Malloc_Mem_Pool, spr_stack);
08702 return (new_wn);
08703 }
08704
08705
08706
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716 static void
08717 Standardize_Do (WN* do_tree)
08718 {
08719 if (WN_operator(WN_end(do_tree)) == OPR_GE
08720 || WN_operator(WN_end(do_tree)) == OPR_LE )
08721 {
08722
08723 return;
08724 }
08725 else
08726 {
08727 WN_Upper_Bound_Standardize(do_tree, WN_end(do_tree), TRUE);
08728 }
08729 }
08730
08731
08732
08733
08734
08735 static void
08736 Extract_Do_Info ( WN * do_tree )
08737 {
08738
08739 Standardize_Do(do_tree);
08740
08741 WN *do_idname = WN_index(do_tree);
08742 ST *do_id_st = WN_st(do_idname);
08743 WN_OFFSET do_id_ofst = WN_offsetx(do_idname);
08744 WN *do_init;
08745 WN *do_limit;
08746 WN *do_stride;
08747 BOOL was_kid0 = FALSE;
08748
08749
08750
08751 do_init = WN_kid0(WN_start(do_tree));
08752 WN_kid0(WN_start(do_tree)) = NULL;
08753
08754 #ifdef KEY
08755 {
08756
08757 WN * kid0 = WN_kid0 (WN_end (do_tree));
08758 if (WN_operator (kid0) == OPR_CVT)
08759 kid0 = WN_kid0 (kid0);
08760
08761 WN * kid1 = WN_kid1 (WN_end (do_tree));
08762 if (WN_operator (kid1) == OPR_CVT)
08763 kid1 = WN_kid0 (kid1);
08764
08765 if (WN_operator (kid0) == OPR_LDID &&
08766 WN_st (kid0) == do_id_st &&
08767 WN_offsetx (kid0) == do_id_ofst)
08768 {
08769 was_kid0 = TRUE;
08770 do_limit = WN_kid1 (WN_end (do_tree));
08771 WN_kid1 (WN_end (do_tree)) = NULL;
08772 }
08773 else if (WN_operator (kid1) == OPR_LDID &&
08774 WN_st (kid1) == do_id_st &&
08775 WN_offsetx (kid1) == do_id_ofst)
08776 {
08777 do_limit = WN_kid0 (WN_end (do_tree));
08778 WN_kid0 (WN_end (do_tree)) = NULL;
08779 }
08780 else
08781 {
08782 WN_Upper_Bound_Standardize ( do_tree, WN_end(do_tree), TRUE );
08783
08784 kid0 = WN_kid0 (WN_end (do_tree));
08785 if (WN_operator (kid0) == OPR_CVT)
08786 kid0 = WN_kid0 (kid0);
08787
08788 kid1 = WN_kid1 (WN_end (do_tree));
08789 if (WN_operator (kid1) == OPR_CVT)
08790 kid1 = WN_kid0 (kid1);
08791
08792 if (WN_operator (kid0) == OPR_LDID &&
08793 WN_st (kid0) == do_id_st &&
08794 WN_offsetx (kid0) == do_id_ofst)
08795 {
08796 was_kid0 = TRUE;
08797 do_limit = WN_kid1 (WN_end (do_tree));
08798 WN_kid1 (WN_end (do_tree)) = NULL;
08799 }
08800 else if (WN_operator (kid1) == OPR_LDID &&
08801 WN_st (kid1) == do_id_st &&
08802 WN_offsetx (kid1) == do_id_ofst)
08803 {
08804 do_limit = WN_kid0 (WN_end (do_tree));
08805 WN_kid0 (WN_end (do_tree)) = NULL;
08806 }
08807 else
08808 Fail_FmtAssertion ( "malformed limit test in MP processing" );
08809 }
08810 }
08811 #else
08812 if ((WN_operator(WN_kid0(WN_end(do_tree))) == OPR_LDID) &&
08813 (WN_st(WN_kid0(WN_end(do_tree))) == do_id_st) &&
08814 (WN_offsetx(WN_kid0(WN_end(do_tree))) == do_id_ofst)) {
08815 was_kid0 = TRUE;
08816 do_limit = WN_kid1(WN_end(do_tree));
08817 WN_kid1(WN_end(do_tree)) = NULL;
08818 } else if ((WN_operator(WN_kid1(WN_end(do_tree))) == OPR_LDID) &&
08819 (WN_st(WN_kid1(WN_end(do_tree))) == do_id_st) &&
08820 (WN_offsetx(WN_kid1(WN_end(do_tree))) == do_id_ofst)) {
08821 do_limit = WN_kid0(WN_end(do_tree));
08822 WN_kid0(WN_end(do_tree)) = NULL;
08823 } else {
08824 WN_Upper_Bound_Standardize ( do_tree, WN_end(do_tree), TRUE );
08825 if ((WN_operator(WN_kid0(WN_end(do_tree))) == OPR_LDID) &&
08826 (WN_st(WN_kid0(WN_end(do_tree))) == do_id_st) &&
08827 (WN_offsetx(WN_kid0(WN_end(do_tree))) == do_id_ofst)) {
08828 was_kid0 = TRUE;
08829 do_limit = WN_kid1(WN_end(do_tree));
08830 WN_kid1(WN_end(do_tree)) = NULL;
08831 } else if ((WN_operator(WN_kid1(WN_end(do_tree))) == OPR_LDID) &&
08832 (WN_st(WN_kid1(WN_end(do_tree))) == do_id_st) &&
08833 (WN_offsetx(WN_kid1(WN_end(do_tree))) == do_id_ofst)) {
08834 do_limit = WN_kid0(WN_end(do_tree));
08835 WN_kid0(WN_end(do_tree)) = NULL;
08836 } else {
08837 Fail_FmtAssertion ( "malformed limit test in MP processing" );
08838 }
08839 }
08840 #endif
08841
08842 if ((WN_operator(WN_kid0(WN_kid0(WN_step(do_tree)))) == OPR_LDID) &&
08843 (WN_st(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_st) &&
08844 (WN_offsetx(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_ofst))
08845 {
08846 do_stride = WN_COPY_Tree ( WN_kid1(WN_kid0(WN_step(do_tree))) );
08847 #ifdef KEY
08848 if (WN_operator (WN_kid0 (WN_step (do_tree))) == OPR_SUB)
08849 {
08850 OPCODE negop = OPCODE_make_op (OPR_NEG, WN_rtype (do_stride), MTYPE_V);
08851 do_stride = WN_CreateExp1 (negop, do_stride);
08852 }
08853 #endif // KEY
08854 }
08855 else
08856 do_stride = WN_COPY_Tree ( WN_kid0(WN_kid0(WN_step(do_tree))) );
08857
08858
08859
08860 base_node = do_init;
08861
08862 limit_node = WN_COPY_Tree( do_limit );
08863
08864 if (((WN_operator(WN_end(do_tree)) == OPR_LT) && was_kid0) ||
08865 ((WN_operator(WN_end(do_tree)) == OPR_GT) && !was_kid0)) {
08866 WN* wn_exp0 = WN_Sub(do_index_type, do_limit, WN_COPY_Tree(do_init));
08867 wn_exp0 = WN_Integer_Cast(wn_exp0, do_index_type, WN_rtype(wn_exp0));
08868 WN* wn_exp1 = WN_Add(do_index_type, wn_exp0, WN_COPY_Tree(do_stride));
08869 wn_exp1 = WN_Integer_Cast(wn_exp1, do_index_type, WN_rtype(wn_exp1));
08870 WN* wn_exp2 = WN_Sub(do_index_type, wn_exp1, WN_Intconst(do_index_type, 1));
08871 wn_exp2 = WN_Integer_Cast(wn_exp2, do_index_type, WN_rtype(wn_exp2));
08872 WN* wn_exp3 = WN_Div(do_index_type, wn_exp2, WN_COPY_Tree(do_stride));
08873 ntrip_node = wn_exp3;
08874 } else if (((WN_operator(WN_end(do_tree)) == OPR_GT) && was_kid0) ||
08875 ((WN_operator(WN_end(do_tree)) == OPR_LT) && !was_kid0)) {
08876 WN* wn_exp0 = WN_Sub(do_index_type, do_limit, WN_COPY_Tree(do_init));
08877 wn_exp0 = WN_Integer_Cast(wn_exp0, do_index_type, WN_rtype(wn_exp0));
08878 WN* wn_exp1 = WN_Add(do_index_type, wn_exp0, WN_Intconst(do_index_type, 1));
08879 wn_exp1 = WN_Integer_Cast(wn_exp1, do_index_type, WN_rtype(wn_exp1));
08880 WN* wn_exp2 = WN_Add(do_index_type, wn_exp1, WN_COPY_Tree(do_stride));
08881 wn_exp2 = WN_Integer_Cast(wn_exp2, do_index_type, WN_rtype(wn_exp2));
08882 WN* wn_exp3 = WN_Div(do_index_type, wn_exp2, WN_COPY_Tree(do_stride));
08883 ntrip_node = wn_exp3;
08884 } else {
08885 WN* wn_exp0 = WN_Sub(do_index_type, do_limit, WN_COPY_Tree(do_init));
08886 wn_exp0 = WN_Integer_Cast(wn_exp0, do_index_type, WN_rtype(wn_exp0));
08887 WN* wn_exp1 = WN_Add(do_index_type, wn_exp0, WN_COPY_Tree(do_stride));
08888 wn_exp1 = WN_Integer_Cast(wn_exp1, do_index_type, WN_rtype(wn_exp1));
08889 WN* wn_exp2 = WN_Div(do_index_type, wn_exp1, WN_COPY_Tree(do_stride));
08890 ntrip_node = wn_exp2;
08891 }
08892 stride_node = do_stride;
08893
08894 }
08895
08896
08897
08898
08899
08900
08901
08902
08903
08904
08905 static WN *
08906 Rewrite_Do_New ( WN * do_tree,
08907 ST * lower,
08908 ST * upper,
08909 ST * stride )
08910 {
08911 WN *loop_info;
08912 WN *do_idname = WN_index(do_tree);
08913 ST *do_id_st = WN_st(do_idname);
08914 WN_OFFSET do_id_ofst = WN_offsetx(do_idname);
08915
08916
08917
08918
08919
08920
08921
08922
08923 if ((ST_sclass(lower) == SCLASS_AUTO) &&
08924 (ST_btype(lower) == MTYPE_I8) &&
08925 ((WN_desc(WN_start(do_tree)) == MTYPE_I1) ||
08926 (WN_desc(WN_start(do_tree)) == MTYPE_I2)))
08927 {
08928 WN_kid0(WN_start(do_tree)) = WN_RLdid ( Promote_Type(MTYPE_I4), MTYPE_I4, 4,
08929 lower, MTYPE_To_TY(MTYPE_I4));
08930 } else
08931 {
08932
08933 WN* wn_local_start = Gen_MP_Load(lower, 0);
08934 WN* wn_new_local_start = WN_Integer_Cast(wn_local_start,
08935 Promote_Type(WN_desc(WN_start(do_tree))), WN_rtype(wn_local_start));
08936 WN_kid0(WN_start(do_tree)) = wn_new_local_start;
08937 }
08938
08939
08940
08941
08942 WN* wn_ldid = Gen_MP_Load( upper, 0 );
08943
08944
08945
08946
08947
08948
08949
08950
08951
08952
08953
08954
08955 WN* wn_cvt_ldid = wn_ldid;
08956 if (WN_rtype(wn_cvt_ldid) != WN_desc(WN_end(do_tree)))
08957 wn_cvt_ldid = WN_Integer_Cast(wn_cvt_ldid, WN_desc(WN_end(do_tree)),
08958 WN_rtype(wn_cvt_ldid));
08959 if (WN_kid0(WN_end(do_tree)) == NULL)
08960 {
08961 WN_kid0(WN_end(do_tree)) = wn_cvt_ldid;
08962 } else
08963 {
08964 WN_kid1(WN_end(do_tree)) = wn_cvt_ldid;
08965 }
08966
08967 if( stride != NULL )
08968 {
08969 wn_ldid = Gen_MP_Load( stride, 0 );
08970 wn_cvt_ldid = wn_ldid;
08971
08972 if( WN_rtype( wn_cvt_ldid ) != WN_desc( WN_step( do_tree )))
08973 {
08974 wn_cvt_ldid = WN_Integer_Cast( wn_cvt_ldid,
08975 WN_desc( WN_step( do_tree )),
08976 WN_rtype( wn_cvt_ldid ));
08977 }
08978 if ((WN_operator(WN_kid0(WN_kid0(WN_step(do_tree)))) == OPR_LDID) &&
08979 (WN_st(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_st) &&
08980 (WN_offsetx(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_ofst))
08981 {
08982 WN_DELETE_Tree( WN_kid1( WN_kid0( WN_step( do_tree ))));
08983 WN_kid1( WN_kid0( WN_step( do_tree ))) = wn_cvt_ldid;
08984 }
08985 else
08986 {
08987 WN_DELETE_Tree( WN_kid0( WN_kid0( WN_step( do_tree ))));
08988 WN_kid0( WN_kid0( WN_step( do_tree ))) = wn_cvt_ldid;
08989 }
08990 }
08991
08992
08993
08994
08995 loop_info = WN_do_loop_info(do_tree);
08996 #ifndef KEY
08997 if (loop_info)
08998 #else
08999
09000
09001
09002
09003
09004
09005
09006
09007 if (loop_info && (!WN_loop_trip(loop_info) ||
09008 !WN_operator_is(WN_loop_trip(loop_info), OPR_INTCONST)))
09009 #endif
09010 {
09011 WN_set_do_loop_info( do_tree, NULL );
09012 WN_set_kid_count( do_tree, 5 );
09013 WN_DELETE_Tree( loop_info );
09014
09015
09016
09017
09018
09019
09020
09021
09022
09023
09024
09025
09026 }
09027 return do_tree;
09028 }
09029
09030
09031
09032
09033
09034
09035
09036
09037
09038 static WN *
09039 Transform_Do( WN * do_tree,
09040 SCHEDULE_TYPE schedule,
09041 WN * chunk_size)
09042 {
09043 WN *wn, *wn_tmp;
09044 WN *do_idname = WN_index(do_tree);
09045 ST *do_id_st = WN_st(do_idname);
09046 WN_OFFSET do_id_ofst = WN_offsetx(do_idname);
09047 WN *do_stride;
09048 WN *do_schedule;
09049 WN *if_wn;
09050 WN *test_wn, *then_wn, *else_wn;
09051 WN *while_wn;
09052 WN *while_test, *while_body;
09053
09054
09055 WN *call_wn;
09056
09057 PREG_NUM rreg1, rreg2;
09058
09059 WN *loop_info;
09060 ST *return_st;
09061 WN_OFFSET return_ofst;
09062 WN *return_wn = WN_CreateBlock( );
09063
09064
09065
09066
09067
09068
09069 WN *do_init_call = NULL;
09070 BOOL is_do32 = TRUE;
09071 BOOL is_LE = TRUE;
09072 BOOL is_kid0_do_id = TRUE;
09073
09074 is_do32 = fast_doacross ? TRUE : FALSE;
09075
09076
09077
09078
09079
09080
09081
09082
09083
09084 if ((WN_operator(WN_kid0(WN_kid0(WN_step(do_tree)))) == OPR_LDID) &&
09085 (WN_st(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_st) &&
09086 (WN_offsetx(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_ofst))
09087 {
09088 do_stride = WN_kid1(WN_kid0(WN_step(do_tree)));
09089 #ifdef KEY
09090 if (WN_operator (WN_kid0 (WN_step (do_tree))) == OPR_SUB)
09091 {
09092 OPCODE negop = OPCODE_make_op (OPR_NEG, WN_rtype (do_stride), MTYPE_V);
09093 do_stride = WN_CreateExp1 (negop, do_stride);
09094 }
09095 #endif // KEY
09096 }
09097 else
09098 do_stride = WN_kid0(WN_kid0(WN_step(do_tree)));
09099
09100
09101
09102
09103
09104 if(( WN_kid0( WN_end( do_tree )) != NULL ) &&
09105 ( WN_operator( WN_kid0( WN_end( do_tree ))) == OPR_LDID ) &&
09106 ( WN_st( WN_kid0( WN_end( do_tree ))) == do_id_st ) &&
09107 ( WN_offsetx( WN_kid0( WN_end( do_tree ))) == do_id_ofst ))
09108 {
09109 is_kid0_do_id = TRUE;
09110 }
09111 else
09112 {
09113 is_kid0_do_id = FALSE;
09114 }
09115 if(( WN_operator( WN_end( do_tree )) == OPR_LT ) ||
09116 ( WN_operator( WN_end( do_tree )) == OPR_LE ))
09117 {
09118 is_LE = TRUE;
09119 }
09120 else
09121 {
09122 is_LE = FALSE;
09123 }
09124 if( is_kid0_do_id == FALSE )
09125 {
09126 if( is_LE == TRUE )
09127 is_LE = FALSE;
09128 else
09129 is_LE = TRUE;
09130 }
09131
09132 do_prefix = WN_CreateBlock( );
09133 do_suffix = WN_CreateBlock( );
09134
09135
09136 wn = WN_COPY_Tree ( limit_node );
09137 wn_tmp = WN_Stid ( do_index_type, limit_ofst,
09138 limit_st, ST_type(limit_st), wn );
09139 WN_INSERT_BlockLast( do_prefix, wn_tmp );
09140
09141
09142
09143
09144
09145
09146
09147
09148
09149
09150
09151
09152
09153
09154
09155
09156
09157
09158
09159 wn_tmp = WN_Stid ( do_index_type, 0,
09160 local_upper, ST_type(local_upper),
09161 Gen_MP_Load( limit_st, limit_ofst ));
09162 WN_linenum( wn_tmp ) = line_number;
09163 WN_INSERT_BlockLast ( do_prefix, wn_tmp );
09164
09165
09166 wn = WN_COPY_Tree( base_node );
09167 wn_tmp = WN_Stid( do_index_type, 0,
09168 local_lower, ST_type(local_lower), wn );
09169 WN_linenum( wn_tmp ) = line_number;
09170 WN_INSERT_BlockLast( do_prefix, wn_tmp );
09171
09172
09173
09174
09175
09176 wn = WN_Stid( MTYPE_I4, 0, last_iter, ST_type( last_iter ),
09177 WN_CreateIntconst( OPC_I4INTCONST, 0 ));
09178 WN_linenum( wn ) = line_number;
09179 WN_INSERT_BlockLast( do_prefix, wn );
09180
09181
09182 do_schedule = WN_CreateIntconst( OPC_I4INTCONST, schedule );
09183
09184
09185
09186
09187
09188
09189
09190
09191
09192
09193
09194
09195
09196
09197 if (( schedule == OMP_SCHED_STATIC_EVEN ) ||
09198 ( schedule == OMP_SCHED_STATIC ))
09199
09200
09201 {
09202
09203 do_init_call = WN_Create( OPC_VCALL, 7);
09204 WN_st_idx( do_init_call ) = GET_MPRUNTIME_ST( is_do32
09205 ? MPR_OMP_STATIC_INIT_4 : MPR_OMP_STATIC_INIT_8 );
09206 WN_Set_Call_Non_Data_Mod( do_init_call );
09207 WN_Set_Call_Non_Data_Ref( do_init_call );
09208 #ifndef KEY // bug 4671
09209 WN_Set_Call_Non_Parm_Mod( do_init_call );
09210 #endif
09211 WN_Set_Call_Non_Parm_Ref( do_init_call );
09212 WN_Set_Call_Parm_Mod( do_init_call );
09213 WN_Set_Call_Parm_Ref( do_init_call );
09214 WN_linenum( do_init_call ) = line_number;
09215
09216 WN_kid( do_init_call, 0 ) = WN_CreateParm( MTYPE_I4,
09217 Gen_MP_Load( local_gtid, 0 ),
09218 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
09219 WN_kid( do_init_call, 1 ) = WN_CreateParm( MTYPE_I4, do_schedule,
09220 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
09221 #ifndef KEY
09222 wn_tmp = WN_Lda( Pointer_type, 0, last_iter );
09223 WN_kid( do_init_call, 2 ) = WN_CreateParm( Pointer_type, wn_tmp,
09224 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09225 #endif
09226 wn_tmp = WN_Lda( Pointer_type, 0, local_lower );
09227 WN_kid( do_init_call, 2 ) = WN_CreateParm( Pointer_type, wn_tmp,
09228 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09229 wn_tmp = WN_Lda( Pointer_type, 0, local_upper );
09230 WN_kid( do_init_call, 3 ) = WN_CreateParm( Pointer_type, wn_tmp,
09231 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09232 wn_tmp = WN_Lda( Pointer_type, 0, local_stride );
09233 WN_kid( do_init_call, 4 ) = WN_CreateParm( Pointer_type, wn_tmp,
09234 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09235
09236 wn = WN_COPY_Tree( do_stride );
09237 wn_tmp = WN_Integer_Cast( wn, is_do32 ? MTYPE_I4 : MTYPE_I8,
09238 WN_rtype( wn ));
09239 WN_kid( do_init_call, 5 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09240 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09241 WN_PARM_BY_VALUE );
09242
09243 wn_tmp = WN_Integer_Cast( chunk_size, is_do32 ? MTYPE_I4 : MTYPE_I8,
09244 WN_rtype( chunk_size ));
09245 WN_kid( do_init_call, 6 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09246 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09247 WN_PARM_BY_VALUE );
09248 }else
09249 {
09250
09251 do_init_call = WN_Create( OPC_VCALL, 6);
09252 WN_st_idx( do_init_call ) = GET_MPRUNTIME_ST( is_do32
09253 ? MPR_OMP_SCHEDULER_INIT_4 : MPR_OMP_SCHEDULER_INIT_8 );
09254 WN_Set_Call_Non_Data_Mod( do_init_call );
09255 WN_Set_Call_Non_Data_Ref( do_init_call );
09256 #ifndef KEY // bug 4671
09257 WN_Set_Call_Non_Parm_Mod( do_init_call );
09258 #endif
09259 WN_Set_Call_Non_Parm_Ref( do_init_call );
09260 WN_Set_Call_Parm_Ref( do_init_call );
09261 WN_linenum( do_init_call ) = line_number;
09262
09263 WN_kid( do_init_call, 0 ) = WN_CreateParm( MTYPE_I4,
09264 Gen_MP_Load( local_gtid, 0 ),
09265 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
09266 WN_kid( do_init_call, 1 ) = WN_CreateParm( MTYPE_I4, do_schedule,
09267 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
09268 wn_tmp = Gen_MP_Load( local_lower, 0 );
09269 WN_kid( do_init_call, 2 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09270 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09271 WN_PARM_BY_VALUE );
09272 wn_tmp = Gen_MP_Load( local_upper, 0 );
09273 WN_kid( do_init_call, 3 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09274 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09275 WN_PARM_BY_VALUE );
09276
09277
09278
09279
09280 wn_tmp = WN_COPY_Tree( do_stride );
09281 wn_tmp = WN_Integer_Cast( wn_tmp, is_do32 ? MTYPE_I4 : MTYPE_I8,
09282 WN_rtype( wn_tmp ));
09283 WN_kid( do_init_call, 4 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09284 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09285 WN_PARM_BY_VALUE );
09286
09287 wn_tmp = WN_Integer_Cast( chunk_size, is_do32 ? MTYPE_I4 : MTYPE_I8,
09288 WN_rtype( chunk_size ));
09289 WN_kid( do_init_call, 5 ) = WN_CreateParm( is_do32 ? MTYPE_I4 : MTYPE_I8,
09290 wn_tmp, Be_Type_Tbl( is_do32 ? MTYPE_I4 : MTYPE_I8 ),
09291 WN_PARM_BY_VALUE );
09292 }
09293
09294 WN_INSERT_BlockLast( do_prefix, do_init_call );
09295
09296 if ( schedule == OMP_SCHED_STATIC_EVEN )
09297
09298 {
09299
09300
09301
09302
09303 if( is_LE )
09304 {
09305 test_wn = WN_GT( do_index_type,
09306 Gen_MP_Load( local_upper, 0 ),
09307 Gen_MP_Load( limit_st, limit_ofst ));
09308 }
09309 else
09310 {
09311 test_wn = WN_LT( do_index_type,
09312 Gen_MP_Load( local_upper, 0 ),
09313 Gen_MP_Load( limit_st, limit_ofst ));
09314 }
09315 then_wn = WN_CreateBlock( );
09316 wn_tmp = WN_Stid ( do_index_type, 0,
09317 local_upper, ST_type(local_upper),
09318 Gen_MP_Load( limit_st, limit_ofst ));
09319 WN_INSERT_BlockLast( then_wn, wn_tmp );
09320 else_wn = WN_CreateBlock( );
09321 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09322 WN_linenum( if_wn ) = line_number;
09323 WN_INSERT_BlockLast( do_prefix, if_wn );
09324
09325 Rewrite_Do_New( do_tree, local_lower, local_upper, NULL );
09326
09327
09328
09329
09330
09331
09332 if ( lastlocal_nodes || nested_lastlocal_nodes )
09333 {
09334 if( is_LE )
09335 {
09336
09337 #ifdef KEY
09338 test_wn = WN_GT (do_index_type,
09339 Gen_MP_Load( WN_st(WN_kid0(do_tree)), WN_offsetx(WN_kid0(do_tree)) ),
09340 Gen_MP_Load( limit_st, limit_ofst ));
09341
09342 #else
09343 test_wn = WN_CAND( WN_LE( do_index_type,
09344 Gen_MP_Load( local_lower, 0 ),
09345 Gen_MP_Load( limit_st, limit_ofst )),
09346 WN_GE( do_index_type,
09347 Gen_MP_Load( local_upper, 0 ),
09348 Gen_MP_Load( limit_st, limit_ofst )));
09349 #endif
09350 }
09351 else
09352 {
09353
09354 #ifdef KEY
09355 test_wn = WN_LT (do_index_type,
09356 Gen_MP_Load( WN_st(WN_kid0(do_tree)), WN_offsetx(WN_kid0(do_tree)) ),
09357 Gen_MP_Load( limit_st, limit_ofst ));
09358 #else
09359 test_wn = WN_CAND( WN_GE( do_index_type,
09360 Gen_MP_Load( local_lower, 0 ),
09361 Gen_MP_Load( limit_st, limit_ofst )),
09362 WN_LE( do_index_type,
09363 Gen_MP_Load( local_upper, 0 ),
09364 Gen_MP_Load( limit_st, limit_ofst )));
09365 #endif
09366 }
09367 then_wn = WN_CreateBlock( );
09368 wn_tmp = WN_Stid ( MTYPE_I4 , 0,
09369 last_iter, ST_type( last_iter ),
09370 WN_CreateIntconst( OPC_I4INTCONST, 1 ));
09371 WN_INSERT_BlockLast( then_wn, wn_tmp );
09372 else_wn = WN_CreateBlock( );
09373 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09374 WN_linenum( if_wn ) = line_number;
09375 WN_INSERT_BlockLast( do_suffix, if_wn );
09376
09377 }
09378
09379
09380 #ifndef KEY
09381 wn = WN_Create( OPC_VCALL, 1 );
09382 WN_st_idx( wn ) = GET_MPRUNTIME_ST( MPR_OMP_STATIC_FINI );
09383 WN_Set_Call_Non_Data_Mod( wn );
09384 WN_Set_Call_Non_Data_Ref( wn );
09385 WN_Set_Call_Non_Parm_Mod( wn );
09386 WN_Set_Call_Non_Parm_Ref( wn );
09387 WN_Set_Call_Parm_Ref( wn );
09388 WN_linenum( wn ) = line_number;
09389
09390 WN_kid0( wn ) = WN_CreateParm( MTYPE_I4,
09391 Gen_MP_Load( local_gtid, 0 ),
09392 Be_Type_Tbl( MTYPE_I4 ),
09393 WN_PARM_BY_VALUE );
09394 WN_INSERT_BlockLast( do_suffix, wn );
09395 #endif
09396
09397
09398 }else if ( schedule == OMP_SCHED_STATIC )
09399
09400 {
09401
09402
09403 if( is_LE)
09404 {
09405 while_test = WN_LE( do_index_type,
09406 Gen_MP_Load( local_lower, 0 ),
09407 Gen_MP_Load( limit_st, limit_ofst ));
09408 }
09409 else
09410 {
09411 while_test = WN_GE( do_index_type,
09412 Gen_MP_Load( local_lower, 0 ),
09413 Gen_MP_Load( limit_st, limit_ofst ));
09414 }
09415
09416 while_body = WN_CreateBlock( );
09417
09418 if( is_LE )
09419 {
09420 test_wn = WN_GT( do_index_type,
09421 Gen_MP_Load( local_upper, 0 ),
09422 Gen_MP_Load( limit_st, limit_ofst ));
09423 }
09424 else
09425 {
09426 test_wn = WN_LT( do_index_type,
09427 Gen_MP_Load( local_upper, 0 ),
09428 Gen_MP_Load( limit_st, limit_ofst ));
09429 }
09430 then_wn = WN_CreateBlock( );
09431 wn_tmp = WN_Stid ( do_index_type, 0,
09432 local_upper, ST_type(local_upper),
09433 Gen_MP_Load( limit_st, limit_ofst ));
09434 WN_INSERT_BlockLast( then_wn, wn_tmp );
09435 else_wn = WN_CreateBlock( );
09436 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09437 WN_linenum( if_wn ) = line_number;
09438 WN_INSERT_BlockLast( while_body, if_wn );
09439
09440 Rewrite_Do_New( do_tree, local_lower, local_upper, NULL);
09441 WN_INSERT_BlockLast( while_body, do_tree );
09442
09443 wn_tmp = WN_Add( do_index_type,
09444 Gen_MP_Load( local_lower, 0 ),
09445 Gen_MP_Load( local_stride, 0 ));
09446 wn = Gen_MP_Store( local_lower, 0, wn_tmp );
09447 WN_INSERT_BlockLast( while_body, wn );
09448 wn_tmp = WN_Add( do_index_type,
09449 Gen_MP_Load( local_upper, 0 ),
09450 Gen_MP_Load( local_stride, 0 ));
09451 wn = Gen_MP_Store( local_upper, 0, wn_tmp );
09452 WN_INSERT_BlockLast( while_body, wn );
09453
09454
09455 while_wn = WN_CreateWhileDo( while_test, while_body );
09456
09457
09458
09459
09460
09461
09462
09463
09464
09465 do_tree = while_wn;
09466
09467
09468
09469 if ( lastlocal_nodes || nested_lastlocal_nodes )
09470 {
09471
09472 wn_tmp = WN_Sub( do_index_type,
09473 Gen_MP_Load( local_lower, 0 ),
09474 Gen_MP_Load( local_stride, 0 ));
09475 wn = Gen_MP_Store( local_lower, 0, wn_tmp );
09476 WN_INSERT_BlockLast( do_suffix, wn );
09477 wn_tmp = WN_Sub( do_index_type,
09478 Gen_MP_Load( local_upper, 0 ),
09479 Gen_MP_Load( local_stride, 0 ));
09480 wn = Gen_MP_Store( local_upper, 0, wn_tmp );
09481 WN_INSERT_BlockLast( do_suffix, wn );
09482 if( is_LE )
09483 {
09484 test_wn = WN_CAND( WN_LE( do_index_type,
09485 Gen_MP_Load( local_lower, 0 ),
09486 Gen_MP_Load( limit_st, limit_ofst )),
09487 WN_GE( do_index_type,
09488 Gen_MP_Load( local_upper, 0 ),
09489 Gen_MP_Load( limit_st, limit_ofst )));
09490 }
09491 else
09492 {
09493 test_wn = WN_CAND( WN_GE( do_index_type,
09494 Gen_MP_Load( local_lower, 0 ),
09495 Gen_MP_Load( limit_st, limit_ofst )),
09496 WN_LE( do_index_type,
09497 Gen_MP_Load( local_upper, 0 ),
09498 Gen_MP_Load( limit_st, limit_ofst )));
09499 }
09500 then_wn = WN_CreateBlock( );
09501 wn_tmp = WN_Stid ( MTYPE_I4 , 0,
09502 last_iter, ST_type( last_iter ),
09503 WN_CreateIntconst( OPC_I4INTCONST, 1 ));
09504 WN_INSERT_BlockLast( then_wn, wn_tmp );
09505 else_wn = WN_CreateBlock( );
09506 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09507 WN_linenum( if_wn ) = line_number;
09508 WN_INSERT_BlockLast( do_suffix, if_wn );
09509
09510 }
09511
09512 #ifndef KEY
09513 wn = WN_Create( OPC_VCALL, 1 );
09514 WN_st_idx( wn ) = GET_MPRUNTIME_ST( MPR_OMP_STATIC_FINI );
09515 WN_Set_Call_Non_Data_Mod( wn );
09516 WN_Set_Call_Non_Data_Ref( wn );
09517 WN_Set_Call_Non_Parm_Mod( wn );
09518 WN_Set_Call_Non_Parm_Ref( wn );
09519 WN_Set_Call_Parm_Ref( wn );
09520 WN_linenum( wn ) = line_number;
09521
09522 WN_kid0( wn ) = WN_CreateParm( MTYPE_I4,
09523 Gen_MP_Load( local_gtid, 0 ),
09524 Be_Type_Tbl( MTYPE_I4 ),
09525 WN_PARM_BY_VALUE );
09526 WN_INSERT_BlockLast( do_suffix, wn );
09527 #endif
09528 }
09529 else
09530 {
09531
09532
09533
09534 call_wn = WN_Create( OPC_I4CALL, 4);
09535 WN_st_idx( call_wn ) = GET_MPRUNTIME_ST( is_do32
09536 ? MPR_OMP_SCHEDULER_NEXT_4 : MPR_OMP_SCHEDULER_NEXT_8 );
09537 WN_Set_Call_Non_Data_Mod( call_wn );
09538 WN_Set_Call_Non_Data_Ref( call_wn );
09539 #ifndef KEY // bug 4671
09540 WN_Set_Call_Non_Parm_Mod( call_wn );
09541 #endif
09542 WN_Set_Call_Non_Parm_Ref( call_wn );
09543 WN_Set_Call_Parm_Mod( call_wn );
09544 WN_Set_Call_Parm_Ref( call_wn );
09545 WN_linenum( call_wn ) = line_number;
09546
09547 WN_kid( call_wn, 0 ) = WN_CreateParm( MTYPE_I4,
09548 Gen_MP_Load( local_gtid, 0),
09549 Be_Type_Tbl( MTYPE_I4 ), WN_PARM_BY_VALUE );
09550 #ifndef KEY
09551 wn_tmp = WN_Lda( Pointer_type, 0, last_iter );
09552 WN_kid( call_wn, 1 ) = WN_CreateParm( Pointer_type, wn_tmp,
09553 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09554 #endif
09555 wn_tmp = WN_Lda( Pointer_type, 0, local_lower );
09556 WN_kid( call_wn, 1 ) = WN_CreateParm( Pointer_type, wn_tmp,
09557 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09558 wn_tmp = WN_Lda( Pointer_type, 0, local_upper );
09559 WN_kid( call_wn, 2 ) = WN_CreateParm( Pointer_type, wn_tmp,
09560 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09561 wn_tmp = WN_Lda( Pointer_type, 0, local_stride );
09562 WN_kid( call_wn, 3 ) = WN_CreateParm( Pointer_type, wn_tmp,
09563 WN_ty( wn_tmp ), WN_PARM_BY_REFERENCE );
09564
09565 WN_INSERT_BlockLast( do_prefix , call_wn );
09566
09567 Create_Preg_or_Temp ( MTYPE_I4, "mpni_status", &return_st, &return_ofst );
09568 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
09569 wn = WN_Stid ( MTYPE_I4, return_ofst, return_st, ST_type(return_st),
09570 WN_LdidPreg ( MTYPE_I4, rreg1 ));
09571 WN_linenum(wn) = line_number;
09572 WN_INSERT_BlockLast( do_prefix , wn );
09573
09574 while_test = Gen_MP_Load( return_st, return_ofst );
09575
09576 while_body = WN_CreateBlock( );
09577
09578 if( is_LE )
09579 {
09580 test_wn = WN_GT( do_index_type,
09581 Gen_MP_Load( local_upper, 0 ),
09582 Gen_MP_Load( limit_st, limit_ofst ));
09583 }
09584 else
09585 {
09586 test_wn = WN_LT( do_index_type,
09587 Gen_MP_Load( local_upper, 0 ),
09588 Gen_MP_Load( limit_st, limit_ofst ));
09589 }
09590 then_wn = WN_CreateBlock( );
09591 wn_tmp = WN_Stid ( do_index_type, 0,
09592 local_upper, ST_type(local_upper),
09593 Gen_MP_Load( limit_st, limit_ofst ));
09594 WN_INSERT_BlockLast( then_wn, wn_tmp );
09595 else_wn = WN_CreateBlock( );
09596 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09597 WN_linenum( if_wn ) = line_number;
09598 WN_INSERT_BlockLast( while_body, if_wn );
09599
09600 Rewrite_Do_New( do_tree, local_lower, local_upper, local_stride);
09601 WN_INSERT_BlockLast( while_body, do_tree );
09602 WN_INSERT_BlockLast( while_body, WN_COPY_Tree( call_wn ));
09603 WN_INSERT_BlockLast( while_body, WN_COPY_Tree( wn ));
09604
09605
09606
09607 while_wn = WN_CreateWhileDo( while_test, while_body );
09608
09609
09610
09611 #ifdef KEY
09612 WN * old_do_tree = do_tree;
09613 {
09614
09615
09616
09617
09618
09619
09620 WN * ldid_lower = WN_Ldid (TY_mtype (Ty_Table[ST_type (local_lower)]),
09621 0,
09622 local_lower,
09623 ST_type (local_lower));
09624 ST * do_index = WN_st (WN_index (old_do_tree));
09625 INT do_offset = WN_offset (WN_index (old_do_tree));
09626 WN * init_do_index = WN_Stid (WN_rtype (ldid_lower),
09627 do_offset,
09628 do_index,
09629 ST_type (do_index),
09630 ldid_lower);
09631 WN_linenum (init_do_index) = line_number;
09632
09633 WN_INSERT_BlockBefore (do_prefix, call_wn, init_do_index);
09634 }
09635 #endif
09636
09637 do_tree = while_wn;
09638
09639
09640 if( lastlocal_nodes || nested_lastlocal_nodes)
09641 {
09642 #ifdef KEY
09643
09644
09645 if( is_LE )
09646 {
09647 test_wn = WN_GT (do_index_type,
09648 Gen_MP_Load( WN_st(WN_kid0(old_do_tree)), WN_offsetx(WN_kid0(old_do_tree)) ),
09649 Gen_MP_Load( limit_st, limit_ofst ));
09650
09651 }
09652 else
09653 {
09654 test_wn = WN_LT (do_index_type,
09655 Gen_MP_Load( WN_st(WN_kid0(old_do_tree)), WN_offsetx(WN_kid0(old_do_tree)) ),
09656 Gen_MP_Load( limit_st, limit_ofst ));
09657 }
09658 then_wn = WN_CreateBlock( );
09659 wn_tmp = WN_Stid ( MTYPE_I4 , 0,
09660 last_iter, ST_type( last_iter ),
09661 WN_CreateIntconst( OPC_I4INTCONST, 1 ));
09662 WN_INSERT_BlockLast( then_wn, wn_tmp );
09663 else_wn = WN_CreateBlock( );
09664 if_wn = WN_CreateIf( test_wn, then_wn, else_wn );
09665 WN_linenum( if_wn ) = line_number;
09666 WN_INSERT_BlockLast( do_suffix, if_wn );
09667 #endif
09668
09669
09670
09671 }
09672 }
09673
09674 WN_INSERT_BlockLast( return_wn, do_prefix );
09675 WN_INSERT_BlockLast( return_wn, do_tree );
09676 WN_INSERT_BlockLast( return_wn, do_suffix );
09677
09678 #ifndef KEY
09679
09680
09681
09682 if( nested_nowait_node == NULL )
09683 {
09684
09685
09686 WN_INSERT_BlockLast( return_wn, Gen_Barrier(local_gtid));
09687
09688
09689 }
09690 else
09691 {
09692 WN_Delete( nested_nowait_node );
09693 nested_nowait_node = NULL;
09694 }
09695 #endif // !KEY
09696
09697 return return_wn;
09698 }
09699
09700
09701
09702
09703 static void
09704 Rewrite_Do ( WN * do_tree )
09705 {
09706 WN *wn;
09707 WN *do_idname = WN_index(do_tree);
09708 ST *do_id_st = WN_st(do_idname);
09709 WN_OFFSET do_id_ofst = WN_offsetx(do_idname);
09710 WN *do_stride;
09711 WN *loop_info;
09712
09713
09714
09715
09716
09717
09718 if ((WN_operator(WN_kid0(WN_kid0(WN_step(do_tree)))) == OPR_LDID) &&
09719 (WN_st(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_st) &&
09720 (WN_offsetx(WN_kid0(WN_kid0(WN_step(do_tree)))) == do_id_ofst))
09721 do_stride = WN_kid1(WN_kid0(WN_step(do_tree)));
09722 else
09723 do_stride = WN_kid0(WN_kid0(WN_step(do_tree)));
09724
09725 Create_Preg_or_Temp ( do_index_type, "do_limit", &limit_st, &limit_ofst );
09726 if ((WN_operator(WN_end(do_tree)) == OPR_LT) ||
09727 (WN_operator(WN_end(do_tree)) == OPR_GT))
09728 wn = WN_Add ( do_index_type,
09729 Gen_MP_Load ( local_start, 0 ),
09730 WN_Mpy ( do_index_type,
09731 Gen_MP_Load ( local_ntrip, 0 ),
09732 WN_COPY_Tree ( do_stride )));
09733 else
09734 wn = WN_Sub ( do_index_type,
09735 WN_Add ( do_index_type,
09736 Gen_MP_Load ( local_start, 0 ),
09737 WN_Mpy ( do_index_type,
09738 Gen_MP_Load ( local_ntrip, 0 ),
09739 WN_COPY_Tree ( do_stride ))),
09740 WN_COPY_Tree ( do_stride ));
09741 do_prefix = WN_Stid ( do_index_type, limit_ofst, limit_st, ST_type(limit_st),
09742 wn );
09743 WN_linenum(do_prefix) = line_number;
09744
09745
09746
09747
09748
09749
09750 if ((ST_sclass(local_start) == SCLASS_AUTO) &&
09751 (ST_btype(local_start) == MTYPE_I8) &&
09752 ((WN_desc(WN_start(do_tree)) == MTYPE_I1) ||
09753 (WN_desc(WN_start(do_tree)) == MTYPE_I2))) {
09754 WN_kid0(WN_start(do_tree)) = WN_RLdid ( Promote_Type(MTYPE_I4), MTYPE_I4, 4,
09755 local_start, MTYPE_To_TY(MTYPE_I4));
09756 } else {
09757
09758 WN* wn_local_start = Gen_MP_Load(local_start, 0);
09759 WN* wn_new_local_start = WN_Integer_Cast(wn_local_start, Promote_Type(WN_desc(WN_start(do_tree))), WN_rtype(wn_local_start));
09760 WN_kid0(WN_start(do_tree)) = wn_new_local_start;
09761 }
09762
09763 WN* wn_ldid = WN_Ldid(do_index_type, limit_ofst, limit_st,
09764 ST_type(limit_st));
09765 WN* wn_cvt_ldid = wn_ldid;
09766 if (WN_rtype(wn_cvt_ldid) != WN_desc(WN_end(do_tree)))
09767 wn_cvt_ldid = WN_Integer_Cast(wn_cvt_ldid, WN_desc(WN_end(do_tree)),
09768 WN_rtype(wn_cvt_ldid));
09769 if (WN_kid0(WN_end(do_tree)) == NULL) {
09770 WN_kid0(WN_end(do_tree)) = wn_cvt_ldid;
09771 } else {
09772 WN_kid1(WN_end(do_tree)) = wn_cvt_ldid;
09773 }
09774
09775
09776
09777 loop_info = WN_do_loop_info(do_tree);
09778 #ifndef KEY
09779 if (loop_info)
09780 #else
09781
09782
09783
09784
09785
09786
09787
09788
09789 if (loop_info && (!WN_loop_trip(loop_info) ||
09790 !WN_operator_is(WN_loop_trip(loop_info), OPR_INTCONST)))
09791 #endif
09792 if (loop_info) {
09793 WN_loop_trip_est(loop_info) = 0;
09794 WN_loop_depth(loop_info) = 1;
09795 WN_Reset_Loop_Nz_Trip ( loop_info );
09796 if (WN_loop_trip(loop_info)) {
09797 WN_DELETE_Tree ( WN_loop_trip(loop_info) );
09798 WN_set_loop_trip ( loop_info, Gen_MP_Load ( local_ntrip, 0 ));
09799 }
09800 }
09801 }
09802
09803
09804
09805
09806
09807
09808
09809 static void
09810 Scale_FB_Parallel_Do(WN *do_loop, float fraction_per_thread)
09811 {
09812 Is_True(do_loop && WN_operator(do_loop) == OPR_DO_LOOP,
09813 ("bad do_loop"));
09814 Is_True(fraction_per_thread <= 1.0, ("bogus fraction_per_thread"));
09815 FB_Info_Loop loop_fil = parallel_pu_fb->Query_loop(do_loop);
09816
09817
09818
09819
09820
09821
09822
09823
09824 if (fraction_per_thread <= 0.5 &&
09825 (fraction_per_thread * loop_fil.freq_iterate.Value() >=
09826 loop_fil.freq_positive.Value())) {
09827
09828
09829
09830 loop_fil.freq_iterate *= fraction_per_thread;
09831 loop_fil.freq_back = loop_fil.freq_iterate - loop_fil.freq_positive;
09832
09833 } else {
09834
09835
09836
09837
09838 return;
09839 }
09840
09841 parallel_pu_fb->Annot_loop(do_loop, loop_fil);
09842
09843
09844 parallel_pu_fb->FB_scale(WN_do_body(do_loop),
09845 FB_FREQ(fraction_per_thread, FALSE));
09846 }
09847
09848
09849 static WN *Process_PDO( WN * pdo_tree );
09850
09851
09852 static void
09853 Transform_Parallel_Block ( WN * tree )
09854 {
09855 INT32 i;
09856 WN *wn;
09857 WN *wn2;
09858 WN *wn3;
09859 WN *wn4;
09860 WN *cur_node;
09861 WN *prev_node;
09862 WN *next_node;
09863 WN *sp_block;
09864 ST *lock_st;
09865
09866 INT32 num_criticals;
09867 BOOL is_omp, is_region;
09868 WN_PRAGMA_ID cur_id, end_id;
09869 INT32 gate_construct_num;
09870
09871 for (cur_node = WN_first(tree); cur_node; cur_node = next_node) {
09872
09873 prev_node = WN_prev(cur_node);
09874 next_node = WN_next(cur_node);
09875
09876 if (((WN_opcode(cur_node) == OPC_PRAGMA) ||
09877 (WN_opcode(cur_node) == OPC_XPRAGMA)) &&
09878 (WN_pragmas[WN_pragma(cur_node)].users & PUSER_MP)) {
09879
09880 switch (cur_id = (WN_PRAGMA_ID) WN_pragma(cur_node)) {
09881
09882 case WN_PRAGMA_BARRIER:
09883
09884
09885 wn = Gen_Barrier(local_gtid);
09886 if (prev_node)
09887 WN_next(prev_node) = wn;
09888 else
09889 WN_first(tree) = wn;
09890 WN_prev(wn) = prev_node;
09891 WN_next(wn) = next_node;
09892 if (next_node)
09893 WN_prev(next_node) = wn;
09894 else
09895 WN_last(tree) = wn;
09896
09897 WN_Delete ( cur_node );
09898 break;
09899
09900
09901 case WN_PRAGMA_ENTER_GATE:
09902
09903 gate_construct_num = ++num_constructs;
09904
09905
09906 wn = WN_CreateBlock();
09907
09908
09909 if (prev_node)
09910 WN_next(prev_node) = wn;
09911 else
09912 WN_first(tree) = wn;
09913 WN_prev(wn) = prev_node;
09914 WN_next(wn) = next_node;
09915 if (next_node)
09916 WN_prev(next_node) = wn;
09917 else
09918 WN_last(tree) = wn;
09919
09920 WN_Delete ( cur_node );
09921 break;
09922
09923 case WN_PRAGMA_EXIT_GATE:
09924
09925
09926
09927 wn = WN_CreateBlock( );
09928
09929
09930 if (prev_node)
09931 WN_next(prev_node) = wn;
09932 else
09933 WN_first(tree) = wn;
09934 WN_prev(wn) = prev_node;
09935 WN_next(wn) = next_node;
09936 if (next_node)
09937 WN_prev(next_node) = wn;
09938 else
09939 WN_last(tree) = wn;
09940
09941 WN_Delete ( cur_node );
09942 break;
09943
09944 case WN_PRAGMA_CRITICAL_SECTION_BEGIN:
09945
09946 if (WN_opcode(cur_node) == OPC_PRAGMA &&
09947 WN_pragma_omp(cur_node) &&
09948 WN_st(cur_node)) {
09949 lock_st = Get_NameLock_ST(WN_st(cur_node));
09950 }
09951 else if ((WN_opcode(cur_node) == OPC_XPRAGMA) &&
09952 (WN_operator(WN_kid0(cur_node)) == OPR_LDA))
09953 lock_st = WN_st(WN_kid0(cur_node));
09954 else if ((WN_opcode(cur_node) == OPC_PRAGMA) && WN_st(cur_node))
09955 lock_st = WN_st(cur_node);
09956 else{
09957 lock_st = NULL;
09958 Create_Unnamed_Critical_Lock( );
09959 }
09960 if (lock_st) {
09961 Linenum_Pusher p(WN_Get_Linenum(cur_node));
09962 wn = Gen_Critical (local_gtid, lock_st);
09963 } else {
09964 Linenum_Pusher p(WN_Get_Linenum(cur_node));
09965 wn = Gen_Critical (local_gtid, unnamed_lock_st);
09966 }
09967 if (prev_node)
09968 WN_next(prev_node) = wn;
09969 else
09970 WN_first(tree) = wn;
09971 WN_prev(wn) = prev_node;
09972 WN_next(wn) = next_node;
09973 if (next_node)
09974 WN_prev(next_node) = wn;
09975 else
09976 WN_last(tree) = wn;
09977
09978 WN_DELETE_Tree ( cur_node );
09979
09980 num_criticals = 1;
09981 cur_node = next_node;
09982 while (cur_node) {
09983 if ((WN_opcode(cur_node) == OPC_PRAGMA) ||
09984 (WN_opcode(cur_node) == OPC_XPRAGMA))
09985 if (WN_pragma(cur_node) == WN_PRAGMA_CRITICAL_SECTION_BEGIN)
09986 ++num_criticals;
09987 else if (WN_pragma(cur_node) == WN_PRAGMA_CRITICAL_SECTION_END)
09988 if ((--num_criticals) == 0)
09989 break;
09990 cur_node = WN_next(cur_node);
09991 }
09992 if (cur_node == NULL)
09993 Fail_FmtAssertion (
09994 "missing pragma (CRITICAL_SECTION_END) in MP processing");
09995 if (lock_st) {
09996 Linenum_Pusher p(WN_Get_Linenum(cur_node));
09997 wn = Gen_End_Critical(local_gtid, lock_st);
09998 } else {
09999 Linenum_Pusher p(WN_Get_Linenum(cur_node));
10000 wn = Gen_End_Critical(local_gtid, unnamed_lock_st);
10001 }
10002 WN_next(WN_prev(cur_node)) = wn;
10003 WN_prev(wn) = WN_prev(cur_node);
10004 WN_next(wn) = WN_next(cur_node);
10005 if (WN_next(cur_node))
10006 WN_prev(WN_next(cur_node)) = wn;
10007 else
10008 WN_last(tree) = wn;
10009
10010 WN_Delete ( cur_node );
10011 break;
10012
10013
10014
10015
10016 case WN_PRAGMA_INDEPENDENT_BEGIN:
10017 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
10018
10019 end_id = (cur_id == WN_PRAGMA_INDEPENDENT_BEGIN) ?
10020 WN_PRAGMA_INDEPENDENT_END : WN_PRAGMA_SINGLE_PROCESS_END;
10021
10022 ++num_constructs;
10023 is_omp = WN_pragma_omp(cur_node);
10024
10025
10026 wn = cur_node;
10027 cur_node = wn2 = WN_next(cur_node);
10028 while (cur_node &&
10029 ((WN_opcode(cur_node) != OPC_PRAGMA) ||
10030 (WN_pragma(cur_node) != end_id)))
10031 cur_node = WN_next(cur_node);
10032 if (!cur_node)
10033 Fail_FmtAssertion(
10034 "missing pragma (INDEPENDENT_END) in MP processing");
10035 wn3 = WN_prev(cur_node);
10036 wn4 = cur_node;
10037 sp_block = WN_CreateBlock();
10038 if (wn2 != wn4) {
10039 WN_EXTRACT_ItemsFromBlock(tree, wn2, wn3);
10040 WN_first(sp_block) = wn2;
10041 WN_last(sp_block) = wn3;
10042 }
10043 WN_DELETE_FromBlock(tree, wn);
10044 WN_DELETE_FromBlock(tree, wn4);
10045
10046 {
10047 WN *mp_sp_block = Gen_MP_SingleProcess_Block(sp_block, FALSE,
10048 #ifdef KEY
10049 NULL,
10050 #endif
10051 is_omp, FALSE);
10052
10053
10054 next_node = WN_first(mp_sp_block);
10055 WN_INSERT_BlockAfter(tree, prev_node, mp_sp_block);
10056 }
10057 break;
10058
10059 case WN_PRAGMA_ORDERED_BEGIN:
10060 WN_INSERT_BlockAfter( tree, prev_node, Gen_Ordered(local_gtid));
10061 WN_DELETE_FromBlock (tree, cur_node);
10062 break;
10063
10064 case WN_PRAGMA_ORDERED_END:
10065 WN_INSERT_BlockAfter( tree, prev_node, Gen_End_Ordered(local_gtid));
10066
10067 WN_DELETE_FromBlock (tree, cur_node);
10068 break;
10069
10070 default:
10071 Fail_FmtAssertion (
10072 "out of context pragma (%s) in MP {parallel region} processing",
10073 WN_pragmas[WN_pragma(cur_node)].name);
10074
10075 }
10076
10077 } else if ((is_region = (WN_opcode(cur_node) == OPC_REGION &&
10078 WN_first(WN_region_pragmas(cur_node)) &&
10079 WN_opcode(WN_first(
10080 WN_region_pragmas(cur_node))) ==
10081 OPC_PRAGMA) ) &&
10082 WN_pragma(WN_first(WN_region_pragmas(cur_node))) ==
10083 WN_PRAGMA_PDO_BEGIN) {
10084
10085 BOOL save_comp_gen_construct = comp_gen_construct;
10086 comp_gen_construct = ( WN_pragma_compiler_generated(
10087 WN_first(WN_region_pragmas(cur_node))) != 0 );
10088 MP_process_type save_mpt = mpt;
10089 mpt = MPP_PDO;
10090
10091 ++num_constructs;
10092 wn = Process_PDO( cur_node );
10093 if (non_pod_finalization_nodes)
10094 Fail_FmtAssertion("out of place non-POD finalization code");
10095
10096 if (WN_first(wn)) {
10097 if (prev_node)
10098 WN_next(prev_node) = WN_first(wn);
10099 else
10100 WN_first(tree) = WN_first(wn);
10101 WN_prev(WN_first(wn)) = prev_node;
10102 WN_next(WN_last(wn)) = next_node;
10103 if (next_node)
10104 WN_prev(next_node) = WN_last(wn);
10105 else
10106 WN_last(tree) = WN_last(wn);
10107 next_node = WN_first(wn);
10108 } else {
10109 if (prev_node)
10110 WN_next(prev_node) = next_node;
10111 else
10112 WN_first(tree) = next_node;
10113 if (next_node)
10114 WN_prev(next_node) = prev_node;
10115 else
10116 WN_last(tree) = prev_node;
10117 }
10118
10119 WN_Delete ( WN_region_pragmas(cur_node) );
10120 WN_DELETE_Tree ( WN_region_exits(cur_node) );
10121 RID_Delete ( Current_Map_Tab, cur_node );
10122 WN_Delete ( cur_node );
10123 WN_Delete ( wn );
10124
10125 comp_gen_construct = save_comp_gen_construct;
10126 mpt = save_mpt;
10127
10128 } else if (is_region &&
10129 WN_first(WN_region_pragmas(cur_node)) &&
10130 WN_pragma(WN_first(WN_region_pragmas(cur_node))) ==
10131 WN_PRAGMA_SINGLE_PROCESS_BEGIN) {
10132
10133 BOOL save_comp_gen_construct = comp_gen_construct;
10134 comp_gen_construct = ( WN_pragma_compiler_generated(
10135 WN_first(WN_region_pragmas(cur_node))) != 0 );
10136 MP_process_type save_mpt = mpt;
10137 mpt = MPP_SINGLE;
10138
10139 ++num_constructs;
10140 wn = Gen_MP_SingleProcess_Region(cur_node);
10141 WN_EXTRACT_FromBlock(tree, cur_node);
10142 WN_INSERT_BlockAfter(tree, prev_node, wn);
10143 WN_DELETE_Tree(WN_region_pragmas(cur_node));
10144 WN_DELETE_Tree(WN_region_exits(cur_node));
10145 RID_Delete(Current_Map_Tab, cur_node);
10146 WN_Delete(cur_node);
10147
10148 comp_gen_construct = save_comp_gen_construct;
10149 mpt = save_mpt;
10150
10151 #ifdef KEY
10152 } else if (is_region &&
10153 WN_first(WN_region_pragmas(cur_node)) &&
10154 WN_pragma(WN_first(WN_region_pragmas(cur_node))) ==
10155 WN_PRAGMA_PWORKSHARE_BEGIN) {
10156
10157 BOOL save_comp_gen_construct = comp_gen_construct;
10158 comp_gen_construct = ( WN_pragma_compiler_generated(
10159 WN_first(WN_region_pragmas(cur_node))) != 0 );
10160 MP_process_type save_mpt = mpt;
10161 mpt = MPP_WORKSHARE;
10162
10163 ++num_constructs;
10164 wn = Gen_MP_Workshare_Region(cur_node);
10165 Transform_Parallel_Block (wn);
10166 WN_EXTRACT_FromBlock(tree, cur_node);
10167 WN_INSERT_BlockAfter(tree, prev_node, wn);
10168 WN_DELETE_Tree(WN_region_pragmas(cur_node));
10169 WN_DELETE_Tree(WN_region_exits(cur_node));
10170 RID_Delete(Current_Map_Tab, cur_node);
10171 WN_Delete(cur_node);
10172
10173 comp_gen_construct = save_comp_gen_construct;
10174 mpt = save_mpt;
10175 #endif
10176
10177 } else if (is_region &&
10178 WN_first(WN_region_pragmas(cur_node)) &&
10179 ( WN_pragma(WN_first(WN_region_pragmas(cur_node))) ==
10180 WN_PRAGMA_MASTER_BEGIN)) {
10181
10182 BOOL save_comp_gen_construct = comp_gen_construct;
10183 comp_gen_construct = ( WN_pragma_compiler_generated(
10184 WN_first(WN_region_pragmas(cur_node))) != 0 );
10185 MP_process_type save_mpt = mpt;
10186 mpt = MPP_MASTER;
10187
10188 ++num_constructs;
10189 wn = Lower_Master(cur_node);
10190 WN_EXTRACT_FromBlock(tree, cur_node);
10191 WN_INSERT_BlockAfter(tree, prev_node, wn);
10192 WN_DELETE_Tree(WN_region_pragmas(cur_node));
10193 WN_DELETE_Tree(WN_region_exits(cur_node));
10194 RID_Delete(Current_Map_Tab, cur_node);
10195 WN_Delete(cur_node);
10196
10197 comp_gen_construct = save_comp_gen_construct;
10198 mpt = save_mpt;
10199
10200 } else {
10201 for (i = 0; i < WN_kid_count(cur_node); i++)
10202 if (WN_kid(cur_node, i) &&
10203 (WN_opcode(WN_kid(cur_node, i)) == OPC_BLOCK))
10204 Transform_Parallel_Block ( WN_kid(cur_node, i) );
10205
10206 }
10207 }
10208 }
10209
10210
10211
10212
10213
10214 SCHEDULE_TYPE
10215 Translate_Schedule_Type( int mp_SchedType,
10216 BOOL ordered)
10217 {
10218 SCHEDULE_TYPE kmpc_schedule_type = OMP_SCHED_UNKNOWN;
10219
10220 switch( mp_SchedType )
10221 {
10222 case WN_PRAGMA_SCHEDTYPE_UNKNOWN:
10223
10224 break;
10225 case WN_PRAGMA_SCHEDTYPE_RUNTIME:
10226 if( ordered )
10227 kmpc_schedule_type = OMP_SCHED_ORDERED_RUNTIME;
10228 else
10229 kmpc_schedule_type = OMP_SCHED_RUNTIME;
10230 break;
10231 case WN_PRAGMA_SCHEDTYPE_SIMPLE:
10232 if( ordered )
10233 kmpc_schedule_type = OMP_SCHED_ORDERED_STATIC_EVEN;
10234 else
10235 kmpc_schedule_type = OMP_SCHED_STATIC_EVEN;
10236 break;
10237 case WN_PRAGMA_SCHEDTYPE_INTERLEAVE:
10238 if( ordered )
10239 kmpc_schedule_type = OMP_SCHED_ORDERED_STATIC;
10240 else
10241 kmpc_schedule_type = OMP_SCHED_STATIC;
10242 break;
10243 case WN_PRAGMA_SCHEDTYPE_DYNAMIC:
10244 if( ordered )
10245 kmpc_schedule_type = OMP_SCHED_ORDERED_DYNAMIC;
10246 else
10247 kmpc_schedule_type = OMP_SCHED_DYNAMIC;
10248 break;
10249 case WN_PRAGMA_SCHEDTYPE_GSS:
10250 if( ordered )
10251 kmpc_schedule_type = OMP_SCHED_ORDERED_GUIDED;
10252 else
10253 kmpc_schedule_type = OMP_SCHED_GUIDED;
10254 break;
10255 case WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED:
10256
10257
10258 if( ordered )
10259 kmpc_schedule_type = OMP_SCHED_ORDERED_STATIC_EVEN;
10260 else
10261 kmpc_schedule_type = OMP_SCHED_STATIC_EVEN;
10262 break;
10263 case MAX_PRAGMA_SCHEDTYPE:
10264
10265 break;
10266 default:
10267
10268 break;
10269 }
10270
10271 return kmpc_schedule_type;
10272 }
10273
10274 #ifdef KEY
10275
10276
10277 static BOOL
10278 Lastpdo_in_Parallel_Region (WN * tree)
10279 {
10280 Is_True (WN_operator (tree) == OPR_REGION &&
10281 WN_region_kind (tree) == REGION_KIND_MP, ("MP region expected"));
10282
10283 RID * rid = REGION_get_rid (tree);
10284 if (!rid) return FALSE;
10285
10286 RID * parent_rid = RID_parent (rid);
10287 Is_True (parent_rid, ("Parent RID cannot be NULL"));
10288
10289 WN * parent = RID_rwn (parent_rid);
10290 if (WN_region_kind (parent) == REGION_KIND_MP)
10291 {
10292
10293
10294
10295
10296
10297
10298
10299
10300 WN * body = WN_region_body (parent);
10301
10302
10303
10304
10305
10306 Is_True (WN_last (body), ("REGION body cannot be null"));
10307
10308 if (WN_last (body) == tree)
10309 return TRUE;
10310 }
10311 return FALSE;
10312 }
10313 #endif // KEY
10314
10315
10316
10317
10318
10319
10320 static WN *
10321 Process_PDO ( WN * tree )
10322 {
10323 INT32 i;
10324 INT32 vsize;
10325 WN *wn;
10326 WN *wn1;
10327 WN *wn2;
10328 WN *cur_node;
10329 WN *first_node;
10330 WN *prev_node;
10331 WN *next_node;
10332 WN *pdo_node;
10333 WN *mpsched_wn;
10334 WN *chunk_wn = NULL;
10335 WN *body_block;
10336 WN *while_block;
10337 WN *reduction_init_block;
10338 WN *reduction_store_block;
10339 ST *return_st;
10340 WN_OFFSET return_ofst;
10341 PREG_NUM rreg1, rreg2;
10342 BOOL while_seen = FALSE;
10343 BOOL is_omp;
10344 BOOL do_dealloca = FALSE;
10345 WN *nested_alloca_block = NULL, *nested_firstprivate_block = NULL;
10346 WN *sp_save_stid;
10347 Alloca_Var_List *avlist;
10348 SCHEDULE_TYPE kmpc_schedule = OMP_SCHED_STATIC_EVEN;
10349
10350
10351
10352
10353
10354 const BOOL orphaned = (mpt == MPP_ORPHANED_PDO);
10355
10356 Is_True(mpt == MPP_PDO || mpt == MPP_ORPHANED_PDO,
10357 ("not inside a PDO loop"));
10358
10359
10360
10361 nested_local_count = 0;
10362 nested_reduction_count = 0;
10363 nested_affinity_nodes = NULL;
10364 nested_affinity_d_nodes = NULL;
10365 nested_affinity_t_nodes = NULL;
10366 nested_chunk_node = NULL;
10367 nested_lastlocal_nodes = NULL;
10368 nested_lastthread_node = NULL;
10369 nested_local_nodes = NULL;
10370 nested_firstprivate_nodes = NULL;
10371 nested_mpsched_node = NULL;
10372 nested_nowait_node = NULL;
10373 nested_ordered_node = NULL;
10374 nested_reduction_nodes = NULL;
10375 nested_shared_nodes = NULL;
10376 nested_do_order_lb = NULL;
10377 nested_do_order_stride = NULL;
10378
10379 if (orphaned) {
10380
10381
10382
10383 psymtab = CURRENT_SYMTAB;
10384 ppuinfo = Current_PU_Info;
10385 pmaptab = Current_Map_Tab;
10386
10387
10388
10389
10390
10391
10392
10393
10394 }
10395
10396 cur_node = WN_first(WN_region_pragmas(tree));
10397
10398 FmtAssert (cur_node &&
10399 WN_opcode(cur_node) == OPC_PRAGMA &&
10400 WN_pragma(cur_node) == WN_PRAGMA_PDO_BEGIN,
10401 ("Process_PDO: Unexpected first pragma node"));
10402 is_omp = WN_pragma_omp(cur_node);
10403
10404 next_node = WN_next(cur_node);
10405 #ifdef KEY
10406 WN_DELETE_FromBlock (WN_region_pragmas(tree), cur_node);
10407 #else
10408 WN_Delete ( cur_node );
10409 #endif
10410
10411 while (cur_node = next_node) {
10412
10413 next_node = WN_next(cur_node);
10414
10415 if (((WN_opcode(cur_node) == OPC_PRAGMA) ||
10416 (WN_opcode(cur_node) == OPC_XPRAGMA)) &&
10417 (WN_pragmas[WN_pragma(cur_node)].users & PUSER_MP)) {
10418
10419 switch (WN_pragma(cur_node)) {
10420
10421 case WN_PRAGMA_AFFINITY:
10422 WN_next(cur_node) = nested_affinity_nodes;
10423 nested_affinity_nodes = cur_node;
10424 break;
10425
10426 case WN_PRAGMA_DATA_AFFINITY:
10427 WN_next(cur_node) = nested_affinity_d_nodes;
10428 nested_affinity_d_nodes = cur_node;
10429 break;
10430
10431 case WN_PRAGMA_THREAD_AFFINITY:
10432 WN_next(cur_node) = nested_affinity_t_nodes;
10433 nested_affinity_t_nodes = cur_node;
10434 break;
10435
10436 case WN_PRAGMA_CHUNKSIZE:
10437 if (nested_chunk_node)
10438 WN_DELETE_Tree ( nested_chunk_node );
10439 nested_chunk_node = cur_node;
10440 break;
10441
10442 case WN_PRAGMA_LASTLOCAL:
10443 for (wn = nested_lastlocal_nodes; wn; wn = WN_next(wn))
10444 if (Identical_Pragmas(cur_node, wn))
10445 break;
10446 if (wn == NULL) {
10447 WN_next(cur_node) = nested_lastlocal_nodes;
10448 nested_lastlocal_nodes = cur_node;
10449 ++nested_local_count;
10450 if (TY_kind(ST_type(WN_st(cur_node))) == KIND_SCALAR)
10451 shared_table[shared_count++] = WN_st(cur_node);
10452 } else
10453 WN_Delete ( cur_node );
10454 break;
10455
10456 case WN_PRAGMA_LASTTHREAD:
10457 if (nested_lastthread_node)
10458 WN_Delete ( nested_lastthread_node );
10459 nested_lastthread_node = cur_node;
10460 break;
10461
10462 case WN_PRAGMA_LOCAL:
10463 for (wn = nested_local_nodes; wn; wn = WN_next(wn))
10464 if (Identical_Pragmas(cur_node, wn))
10465 break;
10466 if (wn == NULL) {
10467 if (ST_Has_Dope_Vector(WN_st(cur_node))) {
10468
10469 WN_next(cur_node) = nested_firstprivate_nodes;
10470 nested_firstprivate_nodes = cur_node;
10471 } else {
10472 WN_next(cur_node) = nested_local_nodes;
10473 nested_local_nodes = cur_node;
10474 }
10475 ++nested_local_count;
10476 } else
10477 WN_Delete ( cur_node );
10478 break;
10479
10480 case WN_PRAGMA_FIRSTPRIVATE:
10481 for (wn = nested_firstprivate_nodes; wn; wn = WN_next(wn))
10482 if (Identical_Pragmas(cur_node, wn))
10483 break;
10484 if (wn == NULL) {
10485 WN_next(cur_node) = nested_firstprivate_nodes;
10486 nested_firstprivate_nodes = cur_node;
10487 ++nested_local_count;
10488 } else
10489 WN_Delete ( cur_node );
10490 break;
10491
10492 case WN_PRAGMA_MPSCHEDTYPE:
10493 if (nested_mpsched_node)
10494 WN_Delete ( nested_mpsched_node );
10495 nested_mpsched_node = cur_node;
10496 break;
10497
10498 case WN_PRAGMA_NOWAIT:
10499 if (nested_nowait_node)
10500 WN_Delete ( nested_nowait_node );
10501 nested_nowait_node = cur_node;
10502 break;
10503
10504 case WN_PRAGMA_ORDERED:
10505 if (nested_ordered_node)
10506 WN_Delete ( nested_ordered_node );
10507 nested_ordered_node = cur_node;
10508 break;
10509
10510 case WN_PRAGMA_ORDERED_LOWER_BOUND:
10511 if (nested_do_order_lb)
10512 WN_Delete (nested_do_order_lb);
10513 nested_do_order_lb = cur_node;
10514 break;
10515
10516 case WN_PRAGMA_ORDERED_STRIDE:
10517 if (nested_do_order_stride)
10518 WN_Delete (nested_do_order_stride);
10519 nested_do_order_stride = cur_node;
10520 break;
10521
10522 case WN_PRAGMA_PDO_END:
10523 case WN_PRAGMA_END_MARKER:
10524 break;
10525
10526 case WN_PRAGMA_REDUCTION:
10527 for (wn = nested_reduction_nodes; wn; wn = WN_next(wn))
10528 if (Identical_Pragmas(cur_node, wn))
10529 break;
10530 if (wn == NULL) {
10531 WN_next(cur_node) = nested_reduction_nodes;
10532 nested_reduction_nodes = cur_node;
10533 ++nested_local_count;
10534 ++nested_reduction_count;
10535 if (WN_opcode(cur_node) == OPC_PRAGMA)
10536 shared_table[shared_count++] = WN_st(cur_node);
10537 } else
10538 WN_DELETE_Tree ( cur_node );
10539 break;
10540
10541
10542
10543 case WN_PRAGMA_SHARED:
10544 for (wn = nested_shared_nodes; wn; wn = WN_next(wn))
10545 if (Identical_Pragmas(cur_node, wn))
10546 break;
10547 if (wn == NULL) {
10548 WN_next(cur_node) = nested_shared_nodes;
10549 nested_shared_nodes = cur_node;
10550 if (TY_kind(ST_type(WN_st(cur_node))) == KIND_SCALAR)
10551 shared_table[shared_count++] = WN_st(cur_node);
10552 } else
10553 WN_Delete ( cur_node );
10554 break;
10555
10556 default:
10557 Fail_FmtAssertion (
10558 "out of context pragma (%s) in MP {region pragma} processing",
10559 WN_pragmas[WN_pragma(cur_node)].name);
10560
10561 }
10562
10563 } else
10564
10565 Fail_FmtAssertion ( "out of context node (%s) in MP{region} processing",
10566 OPCODE_name(WN_opcode(cur_node)) );
10567 }
10568
10569 #ifdef KEY
10570
10571
10572
10573
10574
10575 if (OPT_MP_Barrier_Opt && !nested_nowait_node &&
10576 Lastpdo_in_Parallel_Region (tree))
10577 nested_nowait_node = WN_CreatePragma (WN_PRAGMA_NOWAIT,
10578 (ST_IDX) NULL, 0, 0);
10579 #endif
10580
10581 body_block = WN_region_body(tree);
10582 first_node = pdo_node = WN_first(body_block);
10583 #ifdef KEY
10584
10585
10586 if (pdo_node && WN_operator(pdo_node) == OPR_REGION &&
10587 WN_region_kind(pdo_node) == REGION_KIND_EH
10588 ) {
10589
10590
10591
10592
10593
10594
10595
10596 WN * region_body = WN_region_body(pdo_node);
10597 WN * stmt = WN_first(region_body);
10598 for (; stmt; stmt = WN_next(stmt)) {
10599 if (stmt == WN_last(region_body) &&
10600 WN_opcode(stmt) == OPC_DO_LOOP)
10601 break;
10602 }
10603 Is_True (!stmt || WN_operator(stmt) == OPR_DO_LOOP,
10604 ("Expected statement to be DO_LOOP."));
10605 if (stmt) {
10606
10607 stmt = WN_EXTRACT_FromBlock (region_body, stmt);
10608
10609 WN_INSERT_BlockAfter (body_block, pdo_node, stmt);
10610 first_node = pdo_node = WN_first(body_block);
10611 }
10612 }
10613 #endif
10614 while (pdo_node && (WN_opcode(pdo_node) != OPC_DO_LOOP)) {
10615 if ((WN_opcode(pdo_node) == OPC_DO_WHILE) ||
10616 (WN_opcode(pdo_node) == OPC_WHILE_DO))
10617 while_seen = TRUE;
10618 pdo_node = WN_next(pdo_node);
10619 }
10620
10621
10622
10623
10624 if (orphaned)
10625 {
10626 Strip_Nested_MP( body_block, FALSE );
10627 }
10628
10629 if (pdo_node) {
10630 WN *nested_non_pod_finalization_nodes;
10631
10632 if (non_pod_finalization_nodes) {
10633
10634
10635 if (mpt != MPP_PDO)
10636 Fail_FmtAssertion("out of place non-POD finalization code");
10637 nested_non_pod_finalization_nodes = non_pod_finalization_nodes;
10638 non_pod_finalization_nodes = NULL;
10639 } else
10640 nested_non_pod_finalization_nodes = NULL;
10641
10642 if (nested_local_count) {
10643
10644 vsize = (nested_local_count + 1) * sizeof(VAR_TABLE);
10645 nested_var_table = (VAR_TABLE *) alloca ( vsize );
10646 BZERO ( nested_var_table, vsize );
10647 Create_Local_Variables ( nested_var_table, nested_reduction_nodes,
10648 nested_lastlocal_nodes, nested_local_nodes,
10649 nested_firstprivate_nodes,
10650 &nested_firstprivate_block,
10651 nested_lastthread_node,
10652
10653 orphaned ? &nested_alloca_block :
10654 &alloca_block);
10655 Localize_Parent_Stack lps(orphaned, body_block);
10656
10657 (void) Walk_and_Localize ( pdo_node, nested_var_table, &lps, FALSE,
10658 &nested_non_pod_finalization_nodes );
10659
10660 }
10661
10662 #if 0 //def KEY
10663
10664
10665
10666
10667
10668 if (nested_local_count && !orphaned)
10669 {
10670
10671
10672
10673 SYMTAB_IDX psymtab_l = CURRENT_SYMTAB;
10674 PU_Info * ppuinfo_l = Current_PU_Info;
10675 WN_MAP_TAB * pmaptab_l = Current_Map_Tab;
10676
10677 CURRENT_SYMTAB = psymtab;
10678 Current_PU_Info = ppuinfo;
10679 Current_Map_Tab = pmaptab;
10680
10681
10682 INT32 vsize_l = (nested_local_count + 1) * sizeof (VAR_TABLE);
10683 VAR_TABLE * nested_var_table_l = (VAR_TABLE *) alloca (vsize_l);
10684 ( nested_var_table_l, vsize_l );
10685 Create_Local_Variables ( nested_var_table_l, nested_reduction_nodes,
10686 nested_lastlocal_nodes, nested_local_nodes,
10687 nested_firstprivate_nodes,
10688 &nested_firstprivate_block,
10689 nested_lastthread_node,
10690 &alloca_block );
10691 Localize_Parent_Stack lps_l(orphaned, body_block);
10692 (void) Walk_and_Localize ( serial_stmt_block,
10693 nested_var_table_l, &lps_l, FALSE,
10694 &nested_non_pod_finalization_nodes );
10695
10696 CURRENT_SYMTAB = psymtab_l;
10697 Current_PU_Info = ppuinfo_l;
10698 Current_Map_Tab = pmaptab_l;
10699 }
10700 #endif // KEY
10701
10702 prev_node = WN_prev(pdo_node);
10703 if (prev_node) {
10704
10705 WN *code_before_pdo = WN_CreateBlock();
10706 WN_EXTRACT_ItemsFromBlock(body_block, first_node, prev_node);
10707 WN_first(code_before_pdo) = first_node;
10708 WN_last(code_before_pdo) = prev_node;
10709 WN_INSERT_BlockBefore(body_block, pdo_node, code_before_pdo);
10710 prev_node = WN_prev(pdo_node);
10711 }
10712
10713 WN *code_after_pdo = NULL;
10714 if (WN_next(pdo_node)) {
10715 WN *next_node = WN_next(pdo_node), *last_node = WN_last(body_block);
10716 code_after_pdo = WN_CreateBlock();
10717 WN_EXTRACT_ItemsFromBlock(body_block, next_node, last_node);
10718 WN_first(code_after_pdo) = next_node;
10719 WN_last(code_after_pdo) = last_node;
10720 }
10721 WN_EXTRACT_FromBlock(body_block, pdo_node);
10722
10723
10724
10725 do_index_st = WN_st(WN_index(pdo_node));
10726
10727 do_index_type = TY_mtype(ST_type(do_index_st));
10728 if (do_index_type == MTYPE_I1 || do_index_type == MTYPE_I2)
10729 do_index_type = MTYPE_I4;
10730 else if (do_index_type == MTYPE_U1 || do_index_type == MTYPE_U2)
10731 do_index_type = MTYPE_U4;
10732
10733 #if defined(TARG_X8664) || defined(TARG_MIPS)
10734
10735 if (MTYPE_byte_size(do_index_type) == 4)
10736 #else
10737 if (do_index_type == MTYPE_I4)
10738 #endif
10739 {
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753 fast_doacross = TRUE;
10754 }
10755 else
10756 fast_doacross = FALSE;
10757
10758
10759
10760 Make_Local_Temps( );
10761
10762
10763
10764 Extract_Do_Info ( pdo_node );
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778 do_prefix = NULL;
10779 do_suffix = NULL;
10780
10781 BOOL ordered = ((nested_ordered_node && WN_pragma_omp(nested_ordered_node))||
10782 ( ordered_node && WN_pragma_omp( ordered_node )))
10783 ? TRUE : FALSE;
10784 if ( nested_lastthread_node)
10785 {
10786 if( ordered )
10787 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
10788 else
10789 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
10790 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
10791 }
10792 else if (( ordered_node && !(WN_pragma_omp(ordered_node))) ||
10793 ( nested_ordered_node && !( WN_pragma_omp( nested_ordered_node ))))
10794 {
10795
10796 kmpc_schedule = OMP_SCHED_DYNAMIC;
10797 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
10798 }
10799 else
10800 {
10801 if( nested_mpsched_node )
10802 {
10803 kmpc_schedule = Translate_Schedule_Type( WN_pragma_arg1( nested_mpsched_node ),
10804 ordered );
10805 }
10806 else if( mpsched_node )
10807 kmpc_schedule = Translate_Schedule_Type(WN_pragma_arg1(mpsched_node), ordered);
10808 else if( pu_mpsched_node )
10809 kmpc_schedule = Translate_Schedule_Type(WN_pragma_arg1(pu_mpsched_node), ordered);
10810
10811 else if( nested_chunk_node || chunk_node || pu_chunk_node )
10812 {
10813 if( ordered )
10814 kmpc_schedule = OMP_SCHED_ORDERED_DYNAMIC;
10815 else
10816 kmpc_schedule = OMP_SCHED_DYNAMIC;
10817 }
10818 else
10819 {
10820 if( ordered )
10821 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
10822 else
10823 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
10824 }
10825 if( nested_chunk_node )
10826 {
10827 chunk_wn = WN_COPY_Tree( WN_kid( nested_chunk_node, 0 ));
10828 }
10829 else if( chunk_node )
10830 chunk_wn = WN_COPY_Tree( WN_kid( chunk_node, 0 ));
10831 else if ( pu_chunk_node )
10832 chunk_wn = WN_COPY_Tree( WN_kid( pu_chunk_node, 0 ));
10833 else
10834 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
10835 }
10836
10837
10838 if( kmpc_schedule == OMP_SCHED_UNKNOWN )
10839 {
10840 if( ordered )
10841 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
10842 else
10843 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
10844 }
10845
10846
10847 Is_True( ((kmpc_schedule >= OMP_SCHED_NORMAL_FIRST) &&
10848 (kmpc_schedule <= OMP_SCHED_NORMAL_LAST)) ||
10849 ((kmpc_schedule >= OMP_SCHED_ORDERED_FIRST) &&
10850 (kmpc_schedule <= OMP_SCHED_ORDERED_LAST)),
10851 ( "A schedule type not supported by current RTL" ));
10852
10853
10854
10855
10856
10857
10858
10859
10860 if (nested_alloca_block) {
10861 WN *last = WN_last(nested_alloca_block), *save_last;
10862
10863
10864
10865 if ((do_dealloca = !Calls_Alloca(body_block)) != 0) {
10866 wn = Gen_Save_Stack_Pointer("orphaned_pdo", &sp_save_stid);
10867 save_last = WN_last(wn);
10868 WN_INSERT_BlockAfter(body_block, prev_node, wn);
10869 prev_node = save_last;
10870 avlist = CXX_NEW(Alloca_Var_List(nested_alloca_block),
10871 &mp_lower_pool);
10872 }
10873 WN_INSERT_BlockAfter(body_block, prev_node, nested_alloca_block);
10874 prev_node = last;
10875
10876 Set_PU_has_alloca(Get_Current_PU());
10877 }
10878
10879
10880 if (nested_lastthread_node) {
10881 wn = Gen_MP_Store ( WN_st(nested_lastthread_node),
10882 WN_offsetx(nested_lastthread_node),
10883 WN_Intconst ( MTYPE_I4, 0 ));
10884 WN_INSERT_BlockAfter(body_block, prev_node, wn);
10885 prev_node = wn;
10886 }
10887
10888 if (nested_firstprivate_block) {
10889 Is_True(nested_firstprivate_nodes, ("NULL nested_firstprivate_nodes"));
10890
10891 WN *last = WN_last(nested_firstprivate_block);
10892
10893 WN_INSERT_BlockAfter(body_block, prev_node, nested_firstprivate_block);
10894 prev_node = last;
10895 }
10896
10897
10898
10899
10900 if( orphaned )
10901 {
10902 WN *return_wn = Gen_Store_Gtid();
10903 WN *last = WN_last( return_wn );
10904
10905 WN_INSERT_BlockAfter( body_block, prev_node, return_wn );
10906 prev_node = last;
10907 }
10908
10909 if (nested_reduction_count) {
10910 WN *last;
10911
10912 Gen_MP_Reduction(nested_var_table, nested_local_count,
10913 &reduction_init_block, &reduction_store_block);
10914 last = WN_last(reduction_init_block);
10915 WN_INSERT_BlockAfter(body_block, prev_node, reduction_init_block);
10916 prev_node = last;
10917 }
10918
10919 WN *return_wn = Transform_Do( pdo_node, kmpc_schedule, chunk_wn );
10920 WN *last = WN_last( return_wn );
10921 WN_INSERT_BlockAfter( body_block, prev_node, return_wn );
10922 prev_node = last;
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979 #ifdef KEY
10980 if (code_after_pdo) {
10981
10982
10983 if (nested_var_table && nested_lastlocal_nodes){
10984 Localize_Parent_Stack lps(FALSE, NULL);
10985 code_after_pdo = Walk_and_Localize ( code_after_pdo, nested_var_table, &lps, TRUE,
10986 &nested_non_pod_finalization_nodes );
10987 }
10988 WN_INSERT_BlockBefore(body_block, prev_node, code_after_pdo);
10989 }
10990 #endif
10991 if (nested_lastlocal_nodes || nested_non_pod_finalization_nodes) {
10992 BOOL found_non_pod = FALSE;
10993 WN *first_and_last_mp_barrier = non_pod_first_and_lastprivate ?
10994 Gen_Barrier(local_gtid) : NULL;
10995
10996
10997 wn = WN_CreateBlock ( );
10998 for (i = 0; i < nested_local_count; i++) {
10999 VAR_TABLE *v = &nested_var_table[i];
11000
11001 if (v->vtype == VAR_LASTLOCAL) {
11002
11003
11004
11005 if (v->is_last_and_firstprivate && !first_and_last_mp_barrier)
11006 first_and_last_mp_barrier = Gen_Barrier(local_gtid);
11007
11008
11009
11010 if (!v->is_non_pod) {
11011 WN_INSERT_BlockLast ( wn,
11012 Gen_MP_Load_Store ( v->new_st, v->new_offset,
11013 v->orig_st, v->orig_offset,
11014 v->is_dynamic_array ) );
11015 } else
11016 found_non_pod = TRUE;
11017 }
11018 }
11019
11020
11021 if (nested_non_pod_finalization_nodes) {
11022 if (mpt == MPP_ORPHANED_PDO) {
11023
11024 if (!found_non_pod)
11025 Fail_FmtAssertion("missing non-POD lastprivate clauses");
11026 } else {
11027 #ifndef KEY
11028
11029
11030
11031
11032
11033 if (found_non_pod)
11034
11035 Fail_FmtAssertion("extraneous non-POD lastprivate clauses");
11036 #endif
11037 }
11038 } else {
11039 if (found_non_pod)
11040
11041 Fail_FmtAssertion("missing non-POD finalization code");
11042 }
11043
11044 if (nested_non_pod_finalization_nodes) {
11045 WN *finalization_code = WN_then(nested_non_pod_finalization_nodes);
11046
11047 WN_then(nested_non_pod_finalization_nodes) = NULL;
11048 WN_INSERT_BlockLast(wn, finalization_code);
11049 WN_DELETE_Tree(nested_non_pod_finalization_nodes);
11050 }
11051
11052 if (nested_lastthread_node)
11053 wn = WN_CreateIf ( Gen_MP_Load ( WN_st(nested_lastthread_node),
11054 WN_offsetx(nested_lastthread_node) ),
11055 wn, WN_CreateBlock() );
11056 else
11057 wn = WN_CreateIf ( WN_EQ ( MTYPE_I4,
11058 Gen_MP_Load ( last_iter, 0 ),
11059 WN_CreateIntconst ( OPC_I4INTCONST, 1 )),
11060 wn, WN_CreateBlock() );
11061 WN_linenum(wn) = line_number;
11062
11063
11064 if (first_and_last_mp_barrier) {
11065 WN *blk = WN_CreateBlock();
11066 WN_INSERT_BlockLast(blk, WN_CreateBarrier(TRUE, 0));
11067 WN_INSERT_BlockLast(blk, first_and_last_mp_barrier);
11068 WN_INSERT_BlockLast(blk, WN_CreateBarrier(FALSE, 0));
11069 WN *last = WN_last(blk);
11070 WN_INSERT_BlockAfter(body_block, prev_node, blk);
11071 prev_node = last;
11072 }
11073
11074
11075 {
11076 WN *blk = WN_CreateBlock();
11077 WN_INSERT_BlockLast(blk, WN_CreateBarrier(TRUE, 0));
11078 WN_INSERT_BlockLast(blk, wn);
11079 WN_INSERT_BlockLast(blk, WN_CreateBarrier(FALSE, 0));
11080
11081 #ifdef KEY
11082
11083 if( nested_nowait_node == NULL )
11084 {
11085 WN_INSERT_BlockLast(blk, Gen_Barrier(local_gtid));
11086 }
11087 else
11088 {
11089 WN_Delete(nested_nowait_node);
11090 nested_nowait_node = NULL;
11091 }
11092 #endif // KEY
11093
11094 WN *last = WN_last(blk);
11095 WN_INSERT_BlockAfter(body_block, prev_node, blk);
11096 prev_node = last;
11097 }
11098
11099
11100 WN_INSERT_BlockBefore (WN_then(wn), NULL, WN_CreateBarrier(TRUE,0));
11101 WN_INSERT_BlockAfter (WN_then(wn), NULL, WN_CreateBarrier(FALSE,0));
11102 }
11103 #ifdef KEY
11104 else
11105 {
11106 if( nested_nowait_node == NULL )
11107 {
11108 WN_INSERT_BlockAfter(body_block, prev_node, Gen_Barrier(local_gtid));
11109 prev_node = WN_last (body_block);
11110 }
11111 else
11112 {
11113 WN_Delete(nested_nowait_node);
11114 nested_nowait_node = NULL;
11115 }
11116 }
11117 #endif // KEY
11118
11119 if (nested_reduction_count) {
11120 WN *last = WN_last(reduction_store_block);
11121
11122 WN_INSERT_BlockAfter(body_block, prev_node, reduction_store_block);
11123 prev_node = last;
11124 }
11125
11126
11127
11128 #ifndef KEY
11129 if (nested_nowait_node == NULL || is_omp) {
11130 if (nested_nowait_node == NULL) {
11131
11132 WN *bwn = WN_CreateBarrier(TRUE, 0);
11133 WN_INSERT_BlockAfter(body_block, prev_node, bwn);
11134 prev_node = bwn;
11135 }
11136
11137
11138
11139
11140
11141
11142 if (nested_nowait_node == NULL) {
11143
11144 wn = WN_CreateBarrier(FALSE, 0);
11145 WN_INSERT_BlockAfter(body_block, prev_node, wn);
11146 prev_node = wn;
11147 }
11148 }
11149 #endif
11150
11151
11152
11153
11154
11155
11156
11157 if (do_dealloca) {
11158 WN *restore_block = Gen_Restore_Stack_Pointer(sp_save_stid, avlist);
11159 CXX_DELETE(avlist, &mp_lower_pool);
11160 WN *last = WN_last(restore_block);
11161
11162 WN_INSERT_BlockAfter(body_block, prev_node, restore_block);
11163 prev_node = last;
11164 }
11165 #ifndef KEY
11166 if (code_after_pdo) {
11167
11168 WN *last = WN_last(code_after_pdo);
11169 WN_INSERT_BlockAfter(body_block, prev_node, code_after_pdo);
11170 prev_node = last;
11171 }
11172 #endif
11173 WN_next(prev_node) = NULL;
11174 WN_last(body_block) = prev_node;
11175
11176 if (orphaned)
11177 {
11178 Delayed_MP_Translation( body_block );
11179 }
11180
11181 } else {
11182
11183
11184
11185
11186 if (!while_seen) {
11187 if (WN_first(body_block)) {
11188 WN_DELETE_Tree ( body_block );
11189 body_block = WN_CreateBlock ( );
11190 }
11191 } else
11192 Fail_FmtAssertion
11193 ("parallel DO was converted to WHILE and not converted back");
11194
11195 }
11196
11197
11198
11199
11200
11201 while (nested_affinity_nodes) {
11202 WN *wn = WN_next(nested_affinity_nodes);
11203 WN_DELETE_Tree ( nested_affinity_nodes );
11204 nested_affinity_nodes = wn;
11205 }
11206
11207 while (nested_affinity_d_nodes) {
11208 WN *wn = WN_next(nested_affinity_d_nodes);
11209 WN_DELETE_Tree ( nested_affinity_d_nodes );
11210 nested_affinity_d_nodes = wn;
11211 }
11212
11213 while (nested_affinity_t_nodes) {
11214 WN *wn = WN_next(nested_affinity_t_nodes);
11215 WN_DELETE_Tree ( nested_affinity_t_nodes );
11216 nested_affinity_t_nodes = wn;
11217 }
11218
11219 if (nested_chunk_node)
11220 WN_DELETE_Tree ( nested_chunk_node );
11221
11222 while (nested_lastlocal_nodes) {
11223 WN *wn = WN_next(nested_lastlocal_nodes);
11224 WN_Delete ( nested_lastlocal_nodes );
11225 nested_lastlocal_nodes = wn;
11226 }
11227
11228 if (nested_lastthread_node)
11229 WN_Delete ( nested_lastthread_node );
11230
11231 while (nested_local_nodes) {
11232 WN *wn = WN_next(nested_local_nodes);
11233 WN_Delete ( nested_local_nodes );
11234 nested_local_nodes = wn;
11235 }
11236
11237 while (nested_firstprivate_nodes) {
11238 WN *wn = WN_next(nested_firstprivate_nodes);
11239 WN_Delete ( nested_firstprivate_nodes );
11240 nested_firstprivate_nodes = wn;
11241 }
11242
11243 if (nested_mpsched_node)
11244 WN_Delete ( nested_mpsched_node );
11245
11246 if (nested_nowait_node)
11247 WN_Delete ( nested_nowait_node );
11248
11249 if (nested_ordered_node)
11250 WN_Delete ( nested_ordered_node );
11251
11252 while (nested_reduction_nodes) {
11253 WN *wn = WN_next(nested_reduction_nodes);
11254 WN_Delete ( nested_reduction_nodes );
11255 nested_reduction_nodes = wn;
11256 }
11257
11258 while (nested_shared_nodes) {
11259 WN *wn = WN_next(nested_shared_nodes);
11260 WN_Delete ( nested_shared_nodes );
11261 nested_shared_nodes = wn;
11262 }
11263
11264 for (i=0; i < nested_local_count; i++) {
11265 if (nested_var_table[i].vtree)
11266 WN_DELETE_Tree ( nested_var_table[i].vtree );
11267 if (nested_var_table[i].vtreex)
11268 WN_DELETE_Tree ( nested_var_table[i].vtreex );
11269 }
11270
11271 return (body_block);
11272 }
11273
11274
11275
11276
11277 static void
11278 Process_Parallel_Do ( void )
11279 {
11280 INT32 i;
11281 WN *wn;
11282 WN *lastthread_init = NULL;
11283 WN *reduction_init_block = NULL;
11284 WN *reduction_store_block = NULL;
11285 WN *last_local_if = NULL;
11286
11287 SCHEDULE_TYPE kmpc_schedule = OMP_SCHED_STATIC_EVEN;
11288
11289
11290
11291 WN *chunk_wn = NULL;
11292
11293
11294 Is_True(mpt == MPP_PARALLEL_DO, ("not inside a PARALLEL DO"));
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308 do_prefix = NULL;
11309 do_suffix = NULL;
11310 BOOL ordered = (ordered_node && WN_pragma_omp(ordered_node))
11311 ? TRUE : FALSE;
11312 if ( lastthread_node)
11313 {
11314 if( ordered )
11315 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
11316 else
11317 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
11318 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
11319 }
11320 else if ( ordered_node && !(WN_pragma_omp(ordered_node)))
11321 {
11322
11323 kmpc_schedule = OMP_SCHED_DYNAMIC;
11324 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
11325 }
11326 else
11327 {
11328 if (mpsched_node)
11329 kmpc_schedule = Translate_Schedule_Type(WN_pragma_arg1(mpsched_node), ordered);
11330 else if (pu_mpsched_node)
11331 kmpc_schedule = Translate_Schedule_Type(WN_pragma_arg1(pu_mpsched_node), ordered);
11332 else if (chunk_node || pu_chunk_node)
11333 {
11334 if( ordered )
11335 kmpc_schedule = OMP_SCHED_ORDERED_DYNAMIC;
11336 else
11337 kmpc_schedule = OMP_SCHED_DYNAMIC;
11338 }
11339 else
11340 {
11341 if( ordered )
11342 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
11343 else
11344 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
11345 }
11346 if (chunk_node)
11347 chunk_wn = WN_COPY_Tree( WN_kid(chunk_node, 0));
11348 else if ( pu_chunk_node )
11349 chunk_wn = WN_COPY_Tree( WN_kid(pu_chunk_node, 0));
11350 else
11351 chunk_wn = WN_CreateIntconst( OPC_I4INTCONST, 1 );
11352 }
11353
11354
11355 if( kmpc_schedule == OMP_SCHED_UNKNOWN )
11356 {
11357 if( ordered )
11358 kmpc_schedule = OMP_SCHED_ORDERED_STATIC_EVEN;
11359 else
11360 kmpc_schedule = OMP_SCHED_STATIC_EVEN;
11361 }
11362
11363
11364 Is_True( ((kmpc_schedule >= OMP_SCHED_NORMAL_FIRST) &&
11365 (kmpc_schedule <= OMP_SCHED_NORMAL_LAST)) ||
11366 ((kmpc_schedule >= OMP_SCHED_ORDERED_FIRST) &&
11367 (kmpc_schedule <= OMP_SCHED_ORDERED_LAST)),
11368 ( "A schedule type not supported by current RTL" ));
11369
11370
11371
11372
11373
11374 psymtab = CURRENT_SYMTAB;
11375 ppuinfo = Current_PU_Info;
11376 pmaptab = Current_Map_Tab;
11377
11378
11379
11380
11381 Strip_Nested_MP ( stmt_block, FALSE );
11382
11383
11384
11385 Gather_Inner_Scope_Vlas ( stmt_block );
11386
11387
11388
11389
11390 Extract_Do_Info (do_node);
11391
11392
11393
11394 Process_Preg_Temps ( stmt_block, FALSE );
11395
11396
11397
11398
11399 Push_Some_Globals( );
11400 Create_MicroTask ( fast_doacross ? PAR_FUNC_DO32 : PAR_FUNC_DO64 );
11401 Delayed_MP_Translation( stmt_block );
11402
11403
11404
11405 Create_Local_Variables ( var_table, reduction_nodes, lastlocal_nodes,
11406 local_nodes, firstprivate_nodes,
11407 &firstprivate_block, lastthread_node,
11408 &alloca_block );
11409
11410
11411
11412 Localize_Parent_Stack lps(FALSE, NULL);
11413 stmt_block = Walk_and_Localize ( stmt_block, var_table, &lps, TRUE,
11414 &non_pod_finalization_nodes );
11415
11416 #ifdef KEY
11417 if (LANG_Enable_CXX_Openmp && PU_misc_info(PU_Info_pu(ppuinfo)) &&
11418 PU_src_lang(PU_Info_pu(ppuinfo)) == PU_CXX_LANG)
11419 {
11420 Is_True (parallel_proc, ("Parallel block unavailable"));
11421 PU_IDX pu_idx = ST_pu(parallel_proc);
11422 PU &pu = Pu_Table[pu_idx];
11423 Set_PU_misc_info (pu,
11424 Process_PU_Exc_Info(PU_misc_info (PU_Info_pu(ppuinfo)), var_table));
11425 }
11426
11427
11428 chunk_wn = Walk_and_Localize ( chunk_wn, var_table, &lps, FALSE,
11429 &non_pod_finalization_nodes );
11430
11431 if_preamble_block = Walk_and_Localize ( if_preamble_block, var_table, &lps,
11432 FALSE, &non_pod_finalization_nodes );
11433 do_preamble_block = Walk_and_Localize ( do_preamble_block, var_table, &lps,
11434 FALSE, &non_pod_finalization_nodes );
11435 #endif // KEY
11436
11437
11438
11439 Process_Preamble_Stores ( if_preamble_block, var_table );
11440 Process_Preamble_Stores ( do_preamble_block, var_table );
11441
11442 if (Cur_PU_Feedback) {
11443
11444 Scale_FB_Parallel_Do(do_node, 1.0 / NOMINAL_PROCS);
11445 }
11446
11447
11448
11449
11450
11451
11452 Make_Local_Temps( );
11453 WN *wn_prev_do = WN_prev( do_node );
11454 WN *wn_next_do = WN_next( do_node );
11455 WN_EXTRACT_FromBlock( stmt_block, do_node );
11456
11457 #ifdef KEY
11458 if (!nested_nowait_node)
11459 nested_nowait_node = WN_CreatePragma (WN_PRAGMA_NOWAIT,
11460 (ST_IDX) NULL, 0, 0);
11461 #endif
11462 WN *return_wn = Transform_Do( do_node, kmpc_schedule, chunk_wn );
11463 WN_INSERT_BlockAfter( stmt_block, wn_prev_do, return_wn );
11464 #ifdef KEY
11465 FmtAssert ( nested_nowait_node, ("NULL nested_nowait_node") );
11466 WN_Delete( nested_nowait_node );
11467 nested_nowait_node = NULL;
11468 #endif // KEY
11469
11470 if( do_preamble_block )
11471 {
11472 WN_INSERT_BlockFirst( stmt_block, do_preamble_block );
11473 }
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486 if (copyin_nodes) {
11487 WN_INSERT_BlockFirst (stmt_block, Gen_MP_Copyin(TRUE));
11488 }
11489 #ifdef KEY
11490 Gen_Threadpriv_Func(reference_block, parallel_func, FALSE);
11491 #endif
11492
11493
11494 if (lastthread_node)
11495 lastthread_init = Gen_MP_Store ( WN_st(lastthread_node),
11496 WN_offsetx(lastthread_node),
11497 WN_Intconst ( MTYPE_I4, 0 ));
11498
11499 if (reduction_count)
11500 Gen_MP_Reduction(var_table, local_count, &reduction_init_block,
11501 &reduction_store_block);
11502
11503
11504
11505 BOOL hit_first_last_priv_bug = FALSE;
11506 if (lastlocal_nodes) {
11507
11508 wn = WN_CreateBlock ( );
11509 for (i=0; i < local_count; i++) {
11510 if (var_table[i].vtype == VAR_LASTLOCAL) {
11511
11512
11513
11514 if (var_table[i].is_last_and_firstprivate &&
11515 !hit_first_last_priv_bug) {
11516
11517
11518
11519
11520
11521 ErrMsgLine(EC_MPLOWER_first_last_priv, line_number);
11522 hit_first_last_priv_bug = TRUE;
11523 }
11524
11525 WN_INSERT_BlockLast ( wn,
11526 Gen_MP_Load_Store ( var_table[i].new_st,
11527 var_table[i].new_offset,
11528 var_table[i].orig_st,
11529 var_table[i].orig_offset,
11530 var_table[i].is_dynamic_array ));
11531 }
11532 }
11533 if (lastthread_node)
11534 last_local_if = WN_CreateIf ( Gen_MP_Load ( WN_st(lastthread_node),
11535 WN_offsetx(lastthread_node) ),
11536 wn, WN_CreateBlock ( ) );
11537 else
11538 last_local_if = WN_CreateIf ( WN_EQ( MTYPE_I4,
11539 Gen_MP_Load ( last_iter, 0 ),
11540 WN_CreateIntconst ( OPC_I4INTCONST, 1)),
11541 wn,
11542 WN_CreateBlock( ));
11543 WN_linenum(last_local_if) = line_number;
11544 }
11545
11546
11547
11548 if (alloca_block)
11549 WN_INSERT_BlockLast ( parallel_func, alloca_block );
11550 WN_INSERT_BlockLast ( parallel_func,
11551 WN_CreatePragma ( WN_PRAGMA_PREAMBLE_END, ST_IDX_ZERO,
11552 0, 0 ));
11553 if (firstprivate_block)
11554 WN_INSERT_BlockLast ( parallel_func, firstprivate_block );
11555 if (copyin_block)
11556 WN_INSERT_BlockLast ( parallel_func, copyin_block );
11557 if (lastthread_init)
11558 WN_INSERT_BlockLast ( parallel_func, lastthread_init );
11559 if (reduction_init_block)
11560 WN_INSERT_BlockLast ( parallel_func, reduction_init_block );
11561
11562
11563
11564
11565 WN_INSERT_BlockLast ( parallel_func, stmt_block );
11566
11567
11568 if (last_local_if) {
11569 WN_INSERT_BlockLast(parallel_func, WN_CreateBarrier(FALSE, 0));
11570 WN_INSERT_BlockLast(parallel_func, last_local_if);
11571 WN_INSERT_BlockBefore(WN_then(last_local_if), NULL,
11572 WN_CreateBarrier(TRUE,0));
11573 WN_INSERT_BlockAfter (WN_then(last_local_if), NULL,
11574 WN_CreateBarrier(FALSE,0));
11575 WN_INSERT_BlockLast (parallel_func, WN_CreateBarrier(TRUE, 0));
11576 }
11577 if (reduction_store_block)
11578 WN_INSERT_BlockLast ( parallel_func, reduction_store_block );
11579 if (copyout_block)
11580 WN_INSERT_BlockLast ( parallel_func, copyout_block );
11581
11582
11583
11584 wn = WN_CreateReturn ( );
11585 WN_linenum(wn) = line_number;
11586 WN_INSERT_BlockLast ( parallel_func, wn );
11587
11588
11589
11590 Transfer_Maps ( pmaptab, cmaptab, parallel_func,
11591 PU_Info_regions_ptr(Current_PU_Info) );
11592
11593
11594
11595
11596 Current_Map_Tab = cmaptab;
11597 MP_Fix_Dependence_Graph ( ppuinfo, Current_PU_Info, parallel_func );
11598 Current_Map_Tab = pmaptab;
11599
11600
11601
11602 pu_has_alloca = FALSE;
11603 pu_has_region = FALSE;
11604 WN_TO_BOOL_HASH guarded_set(NUM_HASH_ELEMENTS, Malloc_Mem_Pool);
11605 Gather_Uplevel_References ( reference_block, func_level, NULL, NULL,
11606 parallel_func, &guarded_set );
11607 if (pu_has_alloca) {
11608 Set_PU_has_alloca(Get_Current_PU());
11609 }
11610 if (pu_has_region) {
11611 Set_PU_has_region(Get_Current_PU());
11612 }
11613
11614
11615
11616 CURRENT_SYMTAB = psymtab;
11617 Current_PU_Info = ppuinfo;
11618 Current_pu = &Current_PU_Info_pu();
11619 Current_Map_Tab = pmaptab;
11620 Pop_Some_Globals( );
11621 }
11622
11623
11624
11625
11626 static void
11627 Process_Parallel_Region ( void )
11628 {
11629 WN *wn, *reduction_init_block = NULL, *reduction_store_block = NULL;
11630
11631 Is_True(mpt == MPP_PARALLEL_REGION, ("not in a PARALLEL region"));
11632
11633
11634
11635 psymtab = CURRENT_SYMTAB;
11636 ppuinfo = Current_PU_Info;
11637 pmaptab = Current_Map_Tab;
11638
11639
11640
11641 Strip_Nested_MP ( stmt_block, TRUE );
11642
11643
11644
11645 Gather_Inner_Scope_Vlas ( stmt_block );
11646
11647
11648
11649 Process_Preg_Temps ( stmt_block, TRUE );
11650
11651
11652 Push_Some_Globals( );
11653 Create_MicroTask( PAR_FUNC_REGION );
11654 Delayed_MP_Translation( stmt_block );
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668 Create_Local_Variables ( var_table, reduction_nodes, lastlocal_nodes,
11669 local_nodes, firstprivate_nodes,
11670 &firstprivate_block, NULL, &alloca_block );
11671 Localize_Parent_Stack lps(FALSE, NULL);
11672 stmt_block = Walk_and_Localize ( stmt_block, var_table, &lps, TRUE ,
11673 &non_pod_finalization_nodes );
11674 #ifdef KEY
11675 if (LANG_Enable_CXX_Openmp && PU_Info_pu(ppuinfo).misc)
11676 {
11677 Is_True (parallel_proc, ("Parallel block unavailable"));
11678 PU_IDX pu_idx = ST_pu(parallel_proc);
11679 PU &pu = Pu_Table[pu_idx];
11680
11681 pu.misc = Process_PU_Exc_Info(PU_Info_pu(ppuinfo).misc, var_table);
11682 }
11683 #endif
11684
11685
11686 if (copyin_nodes) {
11687 WN_INSERT_BlockFirst (stmt_block, Gen_MP_Copyin(TRUE));
11688 }
11689
11690 Transform_Parallel_Block ( stmt_block );
11691 #ifdef KEY
11692 Gen_Threadpriv_Func(reference_block, parallel_func, FALSE);
11693 #endif
11694
11695 if (reduction_count)
11696 Gen_MP_Reduction(var_table, local_count, &reduction_init_block,
11697 &reduction_store_block);
11698
11699
11700
11701 if (alloca_block)
11702 WN_INSERT_BlockLast ( parallel_func, alloca_block );
11703 WN_INSERT_BlockLast ( parallel_func,
11704 WN_CreatePragma ( WN_PRAGMA_PREAMBLE_END, ST_IDX_ZERO,
11705 0, 0 ));
11706 if (firstprivate_block)
11707 WN_INSERT_BlockLast ( parallel_func, firstprivate_block );
11708 if (reduction_init_block)
11709 WN_INSERT_BlockLast ( parallel_func, reduction_init_block );
11710 WN_INSERT_BlockLast ( parallel_func, stmt_block );
11711 if (reduction_store_block)
11712 WN_INSERT_BlockLast ( parallel_func, reduction_store_block );
11713
11714
11715
11716 wn = WN_CreateReturn ( );
11717 WN_linenum(wn) = line_number;
11718 WN_INSERT_BlockLast ( parallel_func, wn );
11719
11720
11721
11722 Transfer_Maps ( pmaptab, cmaptab, parallel_func,
11723 PU_Info_regions_ptr(Current_PU_Info) );
11724
11725
11726
11727
11728 Current_Map_Tab = cmaptab;
11729 MP_Fix_Dependence_Graph ( ppuinfo, Current_PU_Info, parallel_func );
11730 Current_Map_Tab = pmaptab;
11731
11732
11733
11734 pu_has_alloca = FALSE;
11735 pu_has_region = FALSE;
11736 WN_TO_BOOL_HASH guarded_set(NUM_HASH_ELEMENTS, Malloc_Mem_Pool);
11737 Gather_Uplevel_References ( reference_block, func_level, NULL, NULL,
11738 parallel_func, &guarded_set );
11739
11740 if (pu_has_alloca) {
11741 Set_PU_has_alloca(Get_Current_PU());
11742 }
11743 if (pu_has_region) {
11744 Set_PU_has_region(Get_Current_PU());
11745 }
11746
11747
11748
11749
11750 CURRENT_SYMTAB = psymtab;
11751 Current_PU_Info = ppuinfo;
11752 Current_pu = &Current_PU_Info_pu();
11753 Current_Map_Tab = pmaptab;
11754 Pop_Some_Globals( );
11755 }
11756
11757
11758 static void Localize_in_serialized_parallel (void)
11759 {
11760 INT32 vsize_l = (local_count + 1) * sizeof(VAR_TABLE);
11761 VAR_TABLE * var_table_l = (VAR_TABLE *) alloca ( vsize_l );
11762 BZERO ( var_table_l, vsize_l );
11763 Create_Local_Variables ( var_table_l, reduction_nodes, lastlocal_nodes,
11764 local_nodes, firstprivate_nodes,
11765 &firstprivate_block, NULL, &alloca_block );
11766 Localize_Parent_Stack lps_l(FALSE, NULL);
11767 serial_stmt_block = Walk_and_Localize ( serial_stmt_block,
11768 var_table_l, &lps_l, FALSE ,
11769 &non_pod_finalization_nodes );
11770 }
11771
11772
11773
11774
11775
11776 WN *
11777 lower_mp ( WN * block, WN * node, INT32 actions )
11778 {
11779 INT32 i;
11780 INT32 vsize;
11781 INT32 lsize;
11782 INT32 ssize;
11783 INT32 msize;
11784 BOOL cont;
11785 WN *wn;
11786 WN *temp_node;
11787 WN *stmt1_block;
11788 WN *stmt2_block;
11789 WN *cur_node;
11790 WN *next_node;
11791 WN *return_nodes;
11792 WN *fp;
11793 WN *mpsched_wn;
11794 WN *chunk_wn;
11795 WN *mp_call_wn;
11796 WN *if_cond_wn;
11797 ST *lock_st;
11798 ST *ntrip_st;
11799 ST *return_st;
11800 WN_OFFSET ntrip_ofst;
11801 WN_OFFSET return_ofst;
11802 PREG_NUM rreg1, rreg2;
11803 INT32 num_criticals;
11804 BOOL while_seen;
11805 BOOL mp_if;
11806
11807
11808
11809 Is_True(actions & LOWER_MP,
11810 ("actions does not contain LOWER_MP"));
11811 Is_True(((WN_opcode(node) == OPC_PRAGMA) ||
11812 (WN_opcode(node) == OPC_XPRAGMA) ||
11813 (WN_opcode(node) == OPC_IF) ||
11814 (WN_opcode(node) == OPC_REGION)),
11815 ("invalid mp node"));
11816
11817 Is_True(PU_Info_proc_sym(Current_PU_Info) == last_pu_proc_sym,
11818 ("LowerMP_PU_Init() not called for this PU"));
11819
11820 Verify_MP_Lowered verify_mp_lowered;
11821 verify_mp_lowered_ptr = &verify_mp_lowered;
11822
11823
11824
11825 if (block == NULL) {
11826
11827 if ((WN_opcode(node) == OPC_PRAGMA) || (WN_opcode(node) == OPC_XPRAGMA)) {
11828
11829 if (WN_pragma(node) == WN_PRAGMA_CHUNKSIZE) {
11830 pu_chunk_node = WN_COPY_Tree ( node );
11831
11832 } else if (WN_pragma(node) == WN_PRAGMA_MPSCHEDTYPE) {
11833 pu_mpsched_node = WN_COPY_Tree ( node );
11834 }
11835
11836 }
11837
11838 verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL);
11839 return (NULL);
11840
11841 }
11842
11843
11844
11845 copyin_count = 0;
11846 local_count = 0;
11847 reduction_count = 0;
11848 shared_count = 0;
11849 num_constructs = 0;
11850 num_criticals = 0;
11851 affinity_nodes = NULL;
11852 affinity_d_nodes = NULL;
11853 affinity_t_nodes = NULL;
11854 chunk_node = NULL;
11855 copyin_nodes = NULL;
11856 copyin_nodes_end = NULL;
11857 if_node = NULL;
11858 lastlocal_nodes = NULL;
11859 lastthread_node = NULL;
11860 local_nodes = NULL;
11861 firstprivate_nodes = NULL;
11862 non_pod_finalization_nodes = NULL;
11863 non_pod_first_and_lastprivate = FALSE;
11864 mpnum_node = NULL;
11865 mpsched_node = NULL;
11866 numthreads_node = NULL;
11867 ordered_node = NULL;
11868 reduction_nodes = NULL;
11869 shared_nodes = NULL;
11870 stmt_block = NULL;
11871 replace_block = NULL;
11872 cont_nodes = NULL;
11873 do_node = NULL;
11874 ntrip_calc = NULL;
11875 livein_block = NULL;
11876 alloca_block = NULL;
11877 copyin_block = NULL;
11878 copyout_block = NULL;
11879 firstprivate_block = NULL;
11880 liveout_block = NULL;
11881 if_cond_wn = NULL;
11882 if_preamble_block = NULL;
11883 if_postamble_block = NULL;
11884 do_preamble_block = NULL;
11885 serial_stmt_block = NULL;
11886 fast_doacross = FALSE;
11887 while_seen = FALSE;
11888 mp_if = FALSE;
11889 do_order_lb = NULL;
11890 do_order_stride = NULL;
11891 inside_versioning_if = FALSE;
11892 comp_gen_construct = FALSE;
11893 mpt = MPP_UNKNOWN;
11894 csymtab = SYMTAB_IDX_ZERO;
11895 psymtab = SYMTAB_IDX_ZERO;
11896 ppuinfo = NULL;
11897 #ifdef KEY
11898 reference_block = NULL;
11899 #endif
11900
11901
11902
11903 inner_scope_vla.clear();
11904
11905
11906 if (first_call) {
11907 MEM_POOL_Initialize(&mp_lower_pool, "MP Lowering Pool", TRUE);
11908 first_call = FALSE;
11909 }
11910 MEM_POOL_Popper popper(&mp_lower_pool);
11911
11912 lsize = sizeof(LABEL_INFO_TABLE) * LABEL_Table_Size(CURRENT_SYMTAB);
11913 label_info_table = (LABEL_INFO_TABLE *) alloca ( lsize );
11914 BZERO ( label_info_table, lsize );
11915
11916 ssize = 4096 * sizeof(SHARED_TABLE);
11917 shared_table = (SHARED_TABLE *) alloca ( ssize );
11918 BZERO ( shared_table, ssize );
11919
11920 if (mpid_size == 0) {
11921 mpid_size = 1028;
11922 msize = mpid_size * sizeof(MPID_TABLE);
11923 mpid_table = (MPID_TABLE *) malloc ( msize );
11924 BZERO ( mpid_table, msize );
11925 }
11926
11927 pu_has_eh = PU_has_exc_scopes(Get_Current_PU());
11928
11929
11930
11931 start_processing:
11932
11933 if ((WN_opcode(node) == OPC_PRAGMA) || (WN_opcode(node) == OPC_XPRAGMA)) {
11934
11935 if (WN_pragma(node) == WN_PRAGMA_BARRIER) {
11936
11937
11938
11939
11940 WN *call, *store_gtid;
11941 wn = WN_next(node);
11942
11943 if (!local_gtid)
11944 {
11945 store_gtid = Gen_Store_Gtid();
11946 }
11947 else
11948 {
11949 store_gtid = WN_CreateBlock();
11950 }
11951 call = Gen_Barrier(local_gtid);
11952 WN_INSERT_BlockLast( store_gtid, call );
11953 WN_next(call) = wn;
11954 if (wn) WN_prev(wn) = call;
11955 WN *return_wn = WN_first( store_gtid );
11956 WN_DELETE_Tree(node);
11957 WN_Delete( store_gtid );
11958 verify_mp_lowered.Set_replace_block_and_nested_pu( return_wn,
11959 WN_next(call), NULL);
11960 return return_wn;
11961
11962 } else if (WN_pragma(node) == WN_PRAGMA_CHUNKSIZE) {
11963 pu_chunk_node = node;
11964 verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL);
11965 return (WN_next(node));
11966
11967 } else if (WN_pragma(node) == WN_PRAGMA_MPSCHEDTYPE) {
11968 pu_mpsched_node = node;
11969 verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL);
11970 return (WN_next(node));
11971
11972 } else if (WN_pragma(node) == WN_PRAGMA_COPYIN) {
11973
11974 mpt = MPP_COPYIN;
11975 next_node = node;
11976
11977 } else if (WN_pragma(node) == WN_PRAGMA_COPYIN_BOUND) {
11978
11979 wn = WN_next(node);
11980 WN_DELETE_Tree ( node );
11981 verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL);
11982 return (wn);
11983
11984 } else if (WN_pragma(node) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
11985
11986 mpt = MPP_CRITICAL_SECTION;
11987 next_node = node;
11988
11989 } else if (WN_pragma(node) == WN_PRAGMA_ORDERED_BEGIN) {
11990
11991
11992
11993
11994 WN *call;
11995 wn = WN_next(node);
11996
11997 WN *store_gtid = Gen_Store_Gtid();
11998 call = Gen_Ordered(local_gtid);
11999 WN_INSERT_BlockLast( store_gtid, call );
12000 WN_next(call) = wn;
12001 if (wn) WN_prev(wn) = call;
12002 WN *return_wn = WN_first( store_gtid );
12003 WN_DELETE_Tree(node);
12004 WN_Delete( store_gtid );
12005 verify_mp_lowered.Set_replace_block_and_nested_pu( return_wn,
12006 WN_next(call), NULL);
12007 return return_wn;
12008
12009 } else if (WN_pragma(node) == WN_PRAGMA_ORDERED_END) {
12010
12011 WN *call;
12012 wn = WN_next(node);
12013
12014 Is_True(local_gtid != NULL, ("unmatched END_ORDERED"));
12015 call = Gen_End_Ordered(local_gtid);
12016 WN_next(call) = wn;
12017 if (wn) WN_prev(wn) = call;
12018 WN_DELETE_Tree(node);
12019 verify_mp_lowered.Set_replace_block_and_nested_pu(call,
12020 WN_next(call), NULL);
12021 return call;
12022
12023 } else
12024
12025 Fail_FmtAssertion (
12026 "out of context pragma (%s) in MP {standalone pragma} processing",
12027 WN_pragmas[WN_pragma(node)].name);
12028
12029 } else if ((WN_opcode(node) == OPC_REGION) &&
12030 WN_first(WN_region_pragmas(node)) &&
12031 ((WN_opcode(WN_first(WN_region_pragmas(node))) == OPC_PRAGMA) ||
12032 (WN_opcode(WN_first(WN_region_pragmas(node))) == OPC_XPRAGMA))) {
12033
12034 WN *wtmp = WN_first(WN_region_pragmas(node));
12035 WN_PRAGMA_ID wid = (WN_PRAGMA_ID) WN_pragma(wtmp);
12036
12037 comp_gen_construct = ( WN_pragma_compiler_generated(
12038 WN_first(WN_region_pragmas(node))) != 0 );
12039
12040 switch (wid) {
12041
12042 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
12043 ++num_constructs;
12044 mpt = MPP_ORPHANED_SINGLE;
12045 Strip_Nested_MP(WN_region_body(node), FALSE);
12046 wn = Gen_MP_SingleProcess_Region(node);
12047 if ((WN_next(wn) = WN_next(node)) != NULL)
12048 WN_prev(WN_next(wn)) = wn;
12049 WN_DELETE_Tree(WN_region_pragmas(node));
12050 WN_DELETE_Tree(WN_region_exits(node));
12051 RID_Delete(Current_Map_Tab, node);
12052 WN_Delete(node);
12053 verify_mp_lowered.Set_replace_block_and_nested_pu(wn, WN_next(wn),
12054 NULL);
12055 return wn;
12056
12057 case WN_PRAGMA_MASTER_BEGIN:
12058 mpt = MPP_ORPHANED_MASTER;
12059 wn = Lower_Master( node );
12060 if ((WN_next(wn) = WN_next(node)) !=NULL)
12061 WN_prev(WN_next(wn)) = wn;
12062 WN_DELETE_Tree(WN_region_pragmas(node));
12063 WN_DELETE_Tree(WN_region_exits(node));
12064 RID_Delete(Current_Map_Tab, node);
12065 WN_Delete(node);
12066 verify_mp_lowered.Set_replace_block_and_nested_pu(wn, WN_next(wn),
12067 NULL);
12068 return wn;
12069
12070 case WN_PRAGMA_DOACROSS:
12071 case WN_PRAGMA_PARALLEL_DO:
12072 mpt = MPP_PARALLEL_DO;
12073 break;
12074
12075 case WN_PRAGMA_PDO_BEGIN:
12076 mpt = MPP_ORPHANED_PDO;
12077 verify_mp_lowered.Set_nested_pu_tree(NULL);
12078 break;
12079
12080 case WN_PRAGMA_PARALLEL_BEGIN:
12081 #ifdef KEY
12082 case WN_PRAGMA_PARALLEL_WORKSHARE:
12083 #endif
12084 mpt = MPP_PARALLEL_REGION;
12085 break;
12086
12087 default:
12088 printf("pragma value = %d", (int)wid);
12089 Fail_FmtAssertion (
12090 "out of context pragma (%s) in MP {primary pragma} processing",
12091 WN_pragmas[wid].name);
12092 }
12093
12094 next_node = WN_next(wtmp);
12095 cont_nodes = WN_next(node);
12096 stmt_block = WN_region_body(node);
12097
12098 if (mpt != MPP_ORPHANED_PDO) {
12099 WN_Delete ( wtmp );
12100 WN_Delete ( WN_region_pragmas(node) );
12101 WN_DELETE_Tree ( WN_region_exits(node) );
12102 }
12103
12104 } else if ((WN_opcode(node) == OPC_IF) && WN_Is_If_MpVersion(node)) {
12105
12106 inside_versioning_if = TRUE;
12107 mp_if = TRUE;
12108 if_cond_wn = WN_if_test(node);
12109 next_node = WN_first(WN_then(node));
12110 serial_stmt_block = WN_else(node);
12111
12112 while (next_node && (WN_opcode(next_node) != OPC_REGION)) {
12113 if (if_preamble_block == NULL)
12114 if_preamble_block = WN_CreateBlock ( );
12115 wn = WN_next(next_node);
12116 WN_INSERT_BlockLast ( if_preamble_block, next_node );
12117 next_node = wn;
12118 }
12119
12120 if (next_node == NULL)
12121 Fail_FmtAssertion (
12122 "missing versioned parallel region in MP processing" );
12123
12124 temp_node = WN_next(next_node);
12125 while (temp_node) {
12126 if (if_postamble_block == NULL)
12127 if_postamble_block = WN_CreateBlock ( );
12128 wn = WN_next(temp_node);
12129 WN_INSERT_BlockLast ( if_postamble_block, temp_node );
12130 temp_node = wn;
12131 }
12132
12133 WN_next(next_node) = WN_next(node);
12134 WN_Delete ( WN_then(node) );
12135 WN_Delete ( node );
12136
12137 node = next_node;
12138 goto start_processing;
12139
12140 } else
12141
12142 Fail_FmtAssertion ( "out of context node (%s) in MP {top-level} processing",
12143 OPCODE_name(WN_opcode(node)) );
12144
12145
12146
12147
12148 cont = (mpt != MPP_ORPHANED_PDO);
12149
12150 while (cont && (cur_node = next_node)) {
12151
12152 next_node = WN_next(cur_node);
12153
12154 if (((WN_opcode(cur_node) == OPC_PRAGMA) ||
12155 (WN_opcode(cur_node) == OPC_XPRAGMA)) &&
12156 (WN_pragmas[WN_pragma(cur_node)].users & PUSER_MP)) {
12157
12158 if (mpt == MPP_COPYIN) {
12159
12160 if (WN_pragma(cur_node) == WN_PRAGMA_COPYIN) {
12161 WN_prev(cur_node) = copyin_nodes_end;
12162 WN_next(cur_node) = NULL;
12163 if (copyin_nodes == NULL)
12164 copyin_nodes_end = copyin_nodes = cur_node;
12165 else
12166 copyin_nodes_end = WN_next(copyin_nodes_end) = cur_node;
12167 ++copyin_count;
12168 } else {
12169 cont_nodes = cur_node;
12170 cont = FALSE;
12171 }
12172
12173 } else if (mpt == MPP_CRITICAL_SECTION) {
12174
12175 if (WN_pragma(cur_node) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) {
12176 if ((num_criticals++) == 0) {
12177 stmt_block = WN_CreateBlock ( );
12178 WN_first(stmt_block) = next_node;
12179 if (next_node)
12180 WN_prev(next_node) = NULL;
12181 }
12182 } else if (WN_pragma(cur_node) == WN_PRAGMA_CRITICAL_SECTION_END) {
12183 if ((--num_criticals) == 0) {
12184 WN_last(stmt_block) = WN_prev(cur_node);
12185 if (WN_prev(cur_node))
12186 WN_next(WN_prev(cur_node)) = NULL;
12187 else
12188 WN_first(stmt_block) = NULL;
12189 cont_nodes = next_node;
12190 cont = FALSE;
12191 }
12192 }
12193
12194 } else {
12195
12196 switch (WN_pragma(cur_node)) {
12197
12198 case WN_PRAGMA_AFFINITY:
12199 WN_next(cur_node) = affinity_nodes;
12200 affinity_nodes = cur_node;
12201 break;
12202
12203 case WN_PRAGMA_DATA_AFFINITY:
12204 WN_next(cur_node) = affinity_d_nodes;
12205 affinity_d_nodes = cur_node;
12206 break;
12207
12208 case WN_PRAGMA_THREAD_AFFINITY:
12209 WN_next(cur_node) = affinity_t_nodes;
12210 affinity_t_nodes = cur_node;
12211 break;
12212
12213 case WN_PRAGMA_CHUNKSIZE:
12214 if (chunk_node)
12215 WN_DELETE_Tree ( chunk_node );
12216 chunk_node = cur_node;
12217 break;
12218
12219 case WN_PRAGMA_IF:
12220 if (if_node)
12221 WN_DELETE_Tree ( if_node );
12222 if_node = cur_node;
12223 break;
12224
12225 case WN_PRAGMA_LASTLOCAL:
12226 for (wn = lastlocal_nodes; wn; wn = WN_next(wn))
12227 if (Identical_Pragmas(cur_node, wn))
12228 break;
12229 if (wn == NULL) {
12230 WN_next(cur_node) = lastlocal_nodes;
12231 lastlocal_nodes = cur_node;
12232 ++local_count;
12233 if (TY_kind(ST_type(WN_st(cur_node))) == KIND_SCALAR)
12234 shared_table[shared_count++] = WN_st(cur_node);
12235 } else
12236 WN_Delete ( cur_node );
12237 break;
12238
12239 case WN_PRAGMA_LASTTHREAD:
12240 if (lastthread_node)
12241 WN_Delete ( lastthread_node );
12242 lastthread_node = cur_node;
12243 break;
12244
12245 case WN_PRAGMA_LOCAL:
12246 for (wn = local_nodes; wn; wn = WN_next(wn))
12247 if (Identical_Pragmas(cur_node, wn))
12248 break;
12249 if (wn == NULL) {
12250 if (ST_Has_Dope_Vector(WN_st(cur_node))) {
12251 WN_next(cur_node) = firstprivate_nodes;
12252 firstprivate_nodes = cur_node;
12253 } else {
12254 WN_next(cur_node) = local_nodes;
12255 local_nodes = cur_node;
12256 }
12257 ++local_count;
12258 } else
12259 WN_Delete ( cur_node );
12260 break;
12261
12262 case WN_PRAGMA_FIRSTPRIVATE:
12263 for (wn = firstprivate_nodes; wn; wn = WN_next(wn))
12264 if (Identical_Pragmas(cur_node, wn))
12265 break;
12266 if (wn == NULL) {
12267 WN_next(cur_node) = firstprivate_nodes;
12268 firstprivate_nodes = cur_node;
12269 ++local_count;
12270 } else
12271 WN_Delete ( cur_node );
12272 break;
12273
12274 case WN_PRAGMA_MPNUM:
12275 if (mpnum_node)
12276 WN_Delete ( mpnum_node );
12277 mpnum_node = cur_node;
12278 break;
12279
12280 case WN_PRAGMA_MPSCHEDTYPE:
12281 if (mpsched_node)
12282 WN_Delete ( mpsched_node );
12283 mpsched_node = cur_node;
12284 break;
12285
12286 case WN_PRAGMA_NUMTHREADS:
12287 if (numthreads_node)
12288 WN_DELETE_Tree ( numthreads_node );
12289 numthreads_node = cur_node;
12290 break;
12291
12292 case WN_PRAGMA_ORDERED:
12293 if (ordered_node)
12294 WN_Delete ( ordered_node );
12295 ordered_node = cur_node;
12296 break;
12297
12298 case WN_PRAGMA_ORDERED_LOWER_BOUND:
12299 if (do_order_lb) WN_Delete (do_order_lb);
12300 do_order_lb = cur_node;
12301 break;
12302
12303 case WN_PRAGMA_ORDERED_STRIDE:
12304 if (do_order_stride) WN_Delete (do_order_stride);
12305 do_order_stride = cur_node;
12306 break;
12307
12308 case WN_PRAGMA_PARALLEL_END:
12309 case WN_PRAGMA_END_MARKER:
12310 break;
12311
12312 case WN_PRAGMA_REDUCTION:
12313 for (wn = reduction_nodes; wn; wn = WN_next(wn))
12314 if (Identical_Pragmas(cur_node, wn))
12315 break;
12316 if (wn == NULL) {
12317 WN_next(cur_node) = reduction_nodes;
12318 reduction_nodes = cur_node;
12319 ++local_count;
12320 ++reduction_count;
12321 if (WN_opcode(cur_node) == OPC_PRAGMA)
12322 shared_table[shared_count++] = WN_st(cur_node);
12323 } else
12324 WN_DELETE_Tree ( cur_node );
12325 break;
12326
12327 case WN_PRAGMA_SHARED:
12328 for (wn = shared_nodes; wn; wn = WN_next(wn))
12329 if (Identical_Pragmas(cur_node, wn))
12330 break;
12331 if (wn == NULL) {
12332 WN_next(cur_node) = shared_nodes;
12333 shared_nodes = cur_node;
12334 if (TY_kind(ST_type(WN_st(cur_node))) == KIND_SCALAR)
12335 shared_table[shared_count++] = WN_st(cur_node);
12336 } else
12337 WN_Delete ( cur_node );
12338 break;
12339
12340 case WN_PRAGMA_COPYIN:
12341 FmtAssert (WN_pragma_omp(cur_node), ("COPYIN clause must be OMP"));
12342 WN_prev(cur_node) = copyin_nodes_end;
12343 WN_next(cur_node) = NULL;
12344 if (copyin_nodes == NULL)
12345 copyin_nodes_end = copyin_nodes = cur_node;
12346 else
12347 copyin_nodes_end = WN_next(copyin_nodes_end) = cur_node;
12348 ++copyin_count;
12349 break;
12350
12351 default:
12352 Fail_FmtAssertion (
12353 "out of context pragma (%s) in MP {top-level pragma} processing",
12354 WN_pragmas[WN_pragma(cur_node)].name);
12355
12356 }
12357
12358 }
12359
12360 } else if (mpt == MPP_COPYIN) {
12361
12362 cont_nodes = cur_node;
12363 cont = FALSE;
12364
12365 } else if (mpt == MPP_CRITICAL_SECTION) {
12366
12367
12368
12369 #ifdef KEY // Bug 6273 - apsi basecompile with -apo triggers this case.
12370 } else if (mpt == MPP_PARALLEL_DO) {
12371
12372
12373
12374 } else if (mpt == MPP_PARALLEL_REGION) {
12375
12376
12377 #endif
12378 } else
12379
12380 Fail_FmtAssertion (
12381 "out of context node (%s) in MP {continuation} processing",
12382 OPCODE_name(WN_opcode(cur_node)) );
12383
12384 }
12385
12386 if (num_criticals != 0)
12387 Fail_FmtAssertion (
12388 "missing pragma (CRITICAL_SECTION_END) in MP processing" );
12389
12390
12391
12392
12393 if (cont_nodes)
12394 WN_prev(cont_nodes) = NULL;
12395
12396 replace_block = WN_CreateBlock ( );
12397
12398 if (mpt == MPP_COPYIN) {
12399
12400 line_number = WN_linenum(node);
12401 Set_Error_Line(line_number);
12402
12403 WN_INSERT_BlockLast ( replace_block, Gen_MP_Copyin ( FALSE ) );
12404
12405 verify_mp_lowered.Set_nested_pu_tree(NULL);
12406
12407 } else if (mpt == MPP_CRITICAL_SECTION) {
12408
12409 line_number = WN_linenum(node);
12410 Set_Error_Line(line_number);
12411
12412 if (WN_opcode(node) == OPC_PRAGMA &&
12413 WN_pragma_omp(node) &&
12414 WN_st(node)) {
12415 lock_st = Get_NameLock_ST(WN_st(node));
12416 }
12417 else if ((WN_opcode(node) == OPC_XPRAGMA) &&
12418 (WN_operator(WN_kid0(node)) == OPR_LDA))
12419 lock_st = WN_st(WN_kid0(node));
12420 else if ((WN_opcode(node) == OPC_PRAGMA) && WN_st(node))
12421 lock_st = WN_st(node);
12422 else{
12423 lock_st = NULL;
12424 Create_Unnamed_Critical_Lock( );
12425 }
12426
12427 if (lock_st) {
12428
12429
12430 Linenum_Pusher p(WN_Get_Linenum(node));
12431 WN_INSERT_BlockLast ( replace_block, Gen_Store_Gtid());
12432 WN_INSERT_BlockLast ( replace_block, Gen_Critical (local_gtid, lock_st));
12433 Strip_Nested_MP ( stmt_block, FALSE );
12434 WN_INSERT_BlockLast ( replace_block, stmt_block );
12435 WN_INSERT_BlockLast ( replace_block, Gen_End_Critical (local_gtid, lock_st));
12436 } else {
12437 Linenum_Pusher p(WN_Get_Linenum(node));
12438 WN_INSERT_BlockLast (replace_block, Gen_Store_Gtid());
12439 WN_INSERT_BlockLast (replace_block, Gen_Critical (local_gtid, unnamed_lock_st));
12440 Strip_Nested_MP ( stmt_block, FALSE );
12441 WN_INSERT_BlockLast ( replace_block, stmt_block );
12442 WN_INSERT_BlockLast ( replace_block, Gen_End_Critical (local_gtid, unnamed_lock_st));
12443 }
12444
12445 WN_DELETE_Tree ( node );
12446 WN_Delete ( cur_node );
12447
12448 verify_mp_lowered.Set_nested_pu_tree(NULL);
12449
12450 } else if (mpt == MPP_PARALLEL_DO) {
12451
12452 BOOL is_omp = WN_pragma_omp(WN_first(WN_region_pragmas(node)));
12453
12454 next_node = WN_first(stmt_block);
12455 while ((do_node = next_node) && (WN_opcode(do_node) != OPC_DO_LOOP)) {
12456 next_node = WN_next(do_node);
12457 if ((WN_opcode(do_node) == OPC_DO_WHILE) ||
12458 (WN_opcode(do_node) == OPC_WHILE_DO))
12459 while_seen = TRUE;
12460 if (do_preamble_block == NULL)
12461 do_preamble_block = WN_CreateBlock ( );
12462 WN_INSERT_BlockLast ( do_preamble_block, do_node );
12463 }
12464 #ifdef KEY //Bug 4660
12465 WN *cur_node;
12466 if (do_preamble_block && lastlocal_nodes){
12467 cur_node = WN_first(do_preamble_block);
12468 while (cur_node){
12469 next_node = WN_next(cur_node);
12470 if (WN_operator(cur_node) == OPR_STID &&
12471 ST_class(WN_st(cur_node)) != CLASS_PREG &&
12472 WN_st(cur_node) == WN_st(lastlocal_nodes))
12473 WN_DELETE_FromBlock(do_preamble_block, cur_node);
12474 cur_node = next_node;
12475 }
12476 }
12477 #endif
12478
12479
12480
12481
12482 if (do_node == NULL) {
12483 if (!while_seen) {
12484 WN_Delete ( stmt_block );
12485 RID_Delete ( Current_Map_Tab, node );
12486 WN_Delete ( node );
12487 local_count = 0;
12488 WN_INSERT_BlockLast ( replace_block, do_preamble_block );
12489 verify_mp_lowered_ptr->Set_nested_pu_tree(NULL);
12490 goto finish_processing;
12491 } else
12492 Fail_FmtAssertion
12493 ("parallel DO was converted to WHILE and not converted back");
12494 }
12495
12496
12497
12498
12499
12500 WN_first(stmt_block) = do_node;
12501 WN_prev(do_node) = NULL;
12502
12503
12504 line_number = WN_linenum(do_node);
12505 Set_Error_Line(line_number);
12506
12507 do_index_st = WN_st(WN_index(do_node));
12508
12509 do_index_type = TY_mtype(ST_type(do_index_st));
12510 if (do_index_type == MTYPE_I1 || do_index_type == MTYPE_I2)
12511 do_index_type = MTYPE_I4;
12512 else if (do_index_type == MTYPE_U1 || do_index_type == MTYPE_U2)
12513 do_index_type = MTYPE_U4;
12514
12515 #if defined(TARG_X8664) || defined(TARG_MIPS)
12516
12517 if (MTYPE_byte_size(do_index_type) == 4)
12518 #else
12519 if (do_index_type == MTYPE_I4)
12520 #endif
12521 {
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535 fast_doacross = TRUE;
12536 }
12537 else
12538 fast_doacross = FALSE;
12539
12540 vsize = (local_count + 1) * sizeof(VAR_TABLE);
12541 var_table = (VAR_TABLE *) alloca ( vsize );
12542 BZERO ( var_table, vsize );
12543
12544 fp = WN_LdidPreg ( Pointer_type, Frame_Pointer_Preg_Offset );
12545
12546 if (serial_stmt_block)
12547 Strip_Nested_MP ( serial_stmt_block, FALSE );
12548 else
12549 serial_stmt_block = Copy_Non_MP_Tree ( stmt_block );
12550
12551
12552
12553
12554 if( do_preamble_block )
12555 {
12556 WN_INSERT_BlockAfter( serial_stmt_block, NULL,
12557 WN_COPY_Tree( do_preamble_block ));
12558 }
12559
12560 #if 0 //def KEY
12561
12562 Localize_in_serialized_parallel ();
12563 #endif
12564
12565
12566
12567 if (is_omp) {
12568 WN *nest_wn;
12569 WN *store_gtid;
12570
12571
12572 store_gtid = Gen_Store_Gtid();
12573 #ifdef KEY
12574 ntrip_calc = WN_CreateBlock ( );
12575 WN *wtree = WN_first(serial_stmt_block);
12576 while (WN_operator(wtree) != OPR_DO_LOOP){
12577 WN_INSERT_BlockLast(ntrip_calc, WN_COPY_Tree(wtree));
12578 wtree = WN_next(wtree);
12579 }
12580 #endif
12581
12582 nest_wn = Gen_Serialized_Parallel( local_gtid);
12583 WN_INSERT_BlockAfter (serial_stmt_block, NULL, nest_wn);
12584
12585 WN_INSERT_BlockAfter( serial_stmt_block, NULL, store_gtid );
12586 nest_wn = Gen_End_Serialized_Parallel (local_gtid);
12587 WN_INSERT_BlockBefore (serial_stmt_block, NULL, nest_wn);
12588 }
12589
12590 Process_Parallel_Do ( );
12591
12592
12593 Cleanup_Ordered (serial_stmt_block, serial_stmt_block);
12594
12595 Create_Preg_or_Temp ( do_index_type, "trip_count", &ntrip_st, &ntrip_ofst );
12596 temp_node = WN_Stid ( do_index_type, ntrip_ofst, ntrip_st,
12597 ST_type(ntrip_st), ntrip_node );
12598 WN_linenum(temp_node) = line_number;
12599 #ifdef KEY
12600 if (!ntrip_calc)
12601 #endif
12602 ntrip_calc = WN_CreateBlock ( );
12603 WN_INSERT_BlockLast ( ntrip_calc, temp_node );
12604 ntrip_node = WN_Ldid ( do_index_type, ntrip_ofst, ntrip_st,
12605 ST_type(ntrip_st) );
12606
12607 if( numthreads_node )
12608 {
12609 mp_call_wn = Gen_Fork ( parallel_proc,
12610 WN_COPY_Tree ( WN_kid0 ( numthreads_node )));
12611 }
12612 else
12613 {
12614 mp_call_wn = Gen_Fork ( parallel_proc, NULL);
12615 }
12616
12617 RID_Delete ( Current_Map_Tab, node );
12618 WN_Delete ( node );
12619
12620 } else if (mpt == MPP_ORPHANED_PDO) {
12621
12622 next_node = WN_first(stmt_block);
12623 while ((do_node = next_node) && (WN_opcode(do_node) != OPC_DO_LOOP)) {
12624 next_node = WN_next(do_node);
12625 if ((WN_opcode(do_node) == OPC_DO_WHILE) ||
12626 (WN_opcode(do_node) == OPC_WHILE_DO))
12627 while_seen = TRUE;
12628 if (do_preamble_block == NULL)
12629 do_preamble_block = WN_CreateBlock ( );
12630 WN_INSERT_BlockLast ( do_preamble_block, do_node );
12631 }
12632
12633 if (do_node == NULL) {
12634 if (!while_seen) {
12635
12636
12637 WN_Delete ( stmt_block );
12638 WN_DELETE_Tree ( WN_region_pragmas(node) );
12639 WN_DELETE_Tree ( WN_region_exits(node) );
12640 RID_Delete ( Current_Map_Tab, node );
12641 WN_Delete ( node );
12642 local_count = 0;
12643 WN_INSERT_BlockLast ( replace_block, do_preamble_block );
12644 verify_mp_lowered_ptr->Set_nested_pu_tree(NULL);
12645 goto finish_processing;
12646 } else
12647 Fail_FmtAssertion
12648 ("PDO was converted to WHILE and not converted back");
12649 }
12650
12651 WN_first(stmt_block) = do_node;
12652 WN_prev(do_node) = NULL;
12653
12654 line_number = WN_linenum(do_node);
12655 Set_Error_Line(line_number);
12656
12657 Strip_Nested_MP(stmt_block, FALSE);
12658 if (serial_stmt_block) {
12659 Is_True(inside_versioning_if,
12660 ("where did serial_stmt_block come from???"));
12661 Move_Non_POD_Finalization_Code(serial_stmt_block);
12662 }
12663 Process_PDO(node);
12664 stmt_block = WN_region_body(node);
12665
12666 WN_Delete ( WN_region_pragmas(node) );
12667 WN_DELETE_Tree ( WN_region_exits(node) );
12668 RID_Delete ( Current_Map_Tab, node );
12669 WN_Delete ( node );
12670
12671 } else if (mpt == MPP_PARALLEL_REGION) {
12672
12673 BOOL is_omp = WN_pragma_omp(WN_first(WN_region_pragmas(node)));
12674
12675 line_number = WN_linenum(node);
12676 Set_Error_Line(line_number);
12677
12678 vsize = (local_count + 1) * sizeof(VAR_TABLE);
12679 var_table = (VAR_TABLE *) alloca ( vsize );
12680 BZERO ( var_table, vsize );
12681
12682 fp = WN_LdidPreg ( Pointer_type, Frame_Pointer_Preg_Offset );
12683
12684 if (serial_stmt_block) {
12685 Is_True(inside_versioning_if,
12686 ("where did serial_stmt_block come from???"));
12687 Move_Non_POD_Finalization_Code(serial_stmt_block);
12688 Strip_Nested_MP ( serial_stmt_block, FALSE );
12689 } else
12690 serial_stmt_block = Copy_Non_MP_Tree ( stmt_block );
12691
12692 #if 0 //def KEY
12693
12694 Localize_in_serialized_parallel ();
12695 #endif
12696
12697 Process_Parallel_Region ( );
12698
12699 #ifndef KEY // bug 7281
12700 if (is_omp) {
12701 #endif
12702 WN *nest_wn;
12703
12704 if( numthreads_node )
12705 {
12706 mp_call_wn = Gen_Fork ( parallel_proc,
12707 WN_COPY_Tree ( WN_kid0 ( numthreads_node )));
12708 }
12709 else
12710 {
12711 mp_call_wn = Gen_Fork ( parallel_proc, NULL);
12712 }
12713
12714
12715
12716 WN *store_gtid = Gen_Store_Gtid();
12717 nest_wn = Gen_Serialized_Parallel (local_gtid);
12718 WN_INSERT_BlockAfter (serial_stmt_block, NULL, nest_wn);
12719 WN_INSERT_BlockAfter (serial_stmt_block, NULL, store_gtid);
12720
12721
12722
12723 Cleanup_Ordered (serial_stmt_block, serial_stmt_block);
12724
12725 nest_wn = Gen_End_Serialized_Parallel (local_gtid);
12726 WN_INSERT_BlockBefore (serial_stmt_block, NULL, nest_wn);
12727 #ifndef KEY // bug 7281
12728 }
12729 else
12730 {
12731
12732
12733
12734
12735 }
12736 #endif
12737
12738 RID_Delete ( Current_Map_Tab, node );
12739 WN_Delete ( node );
12740
12741 }
12742
12743
12744
12745 if ((mpt == MPP_PARALLEL_DO) || (mpt == MPP_PARALLEL_REGION)) {
12746
12747
12748 stmt1_block = WN_CreateBlock ( );
12749 if (mp_if) {
12750 if (if_preamble_block)
12751 WN_INSERT_BlockLast ( stmt1_block, if_preamble_block );
12752 if (do_preamble_block)
12753 WN_INSERT_BlockLast ( stmt1_block, do_preamble_block );
12754 if (ntrip_calc)
12755 WN_INSERT_BlockLast ( stmt1_block, ntrip_calc );
12756 }
12757 if (livein_block)
12758 WN_INSERT_BlockLast ( stmt1_block, livein_block );
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769 WN_INSERT_BlockLast( stmt1_block, mp_call_wn );
12770
12771 if (liveout_block) {
12772
12773
12774
12775
12776 WN_INSERT_BlockLast ( stmt1_block, liveout_block );
12777 }
12778 if (mp_if && if_postamble_block)
12779 WN_INSERT_BlockLast ( stmt1_block, if_postamble_block );
12780
12781 if (!mp_if) {
12782 if ((do_preamble_block) && (mpt != MPP_PARALLEL_DO ))
12783 WN_INSERT_BlockLast ( replace_block, do_preamble_block );
12784 if (ntrip_calc)
12785 WN_INSERT_BlockLast ( replace_block, ntrip_calc );
12786 if (if_node)
12787 if_cond_wn = WN_COPY_Tree ( WN_kid0(if_node) );
12788 if (mpt == MPP_PARALLEL_DO) {
12789
12790 temp_node = WN_GT ( do_index_type, WN_Ldid ( do_index_type, ntrip_ofst,
12791 ntrip_st, ST_type(ntrip_st) ),
12792 WN_Intconst ( do_index_type, 1 ));
12793 if (if_cond_wn)
12794 if_cond_wn = WN_CAND ( if_cond_wn, temp_node );
12795 else
12796 if_cond_wn = temp_node;
12797 }
12798
12799 #ifndef KEY
12800 ST *in_parallel_st;
12801 WN_OFFSET in_parallel_ofst;
12802 Create_Preg_or_Temp( MTYPE_I4, "__ompv_in_parallel",
12803 &in_parallel_st, &in_parallel_ofst);
12804 WN_INSERT_BlockLast( replace_block, Gen_In_Parallel( ));
12805 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
12806 temp_node = Gen_MP_Store( in_parallel_st, in_parallel_ofst,
12807 WN_LdidPreg( MTYPE_I4, rreg1 ));
12808 WN_linenum(temp_node) = line_number;
12809 WN_INSERT_BlockLast( replace_block, temp_node );
12810 #endif
12811
12812 ST *ok_to_fork_st;
12813 WN_OFFSET ok_to_fork_ofst;
12814 Create_Preg_or_Temp( MTYPE_I4, "__ompv_ok_to_fork",
12815 &ok_to_fork_st, &ok_to_fork_ofst);
12816 #ifndef KEY // bug 7772
12817 WN_INSERT_BlockLast( replace_block, Gen_Can_Fork( ));
12818 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
12819 temp_node = Gen_MP_Store( ok_to_fork_st, ok_to_fork_ofst,
12820 WN_LdidPreg( MTYPE_I4, rreg1 ));
12821 WN_linenum(temp_node) = line_number;
12822 WN_INSERT_BlockLast( replace_block, temp_node );
12823
12824 #ifdef KEY
12825 temp_node = WN_EQ( MTYPE_I4,
12826 Gen_MP_Load( ok_to_fork_st, ok_to_fork_ofst ),
12827 WN_CreateIntconst(OPC_I4INTCONST, 1));
12828 #else
12829 temp_node = WN_CAND( WN_EQ( MTYPE_I4,
12830 Gen_MP_Load( in_parallel_st, in_parallel_ofst ),
12831 WN_CreateIntconst(OPC_I4INTCONST, 0)),
12832 WN_EQ( MTYPE_I4,
12833 Gen_MP_Load( ok_to_fork_st, ok_to_fork_ofst ),
12834 WN_CreateIntconst(OPC_I4INTCONST, 1)));
12835 #endif
12836
12837
12838
12839 if (if_cond_wn)
12840 if_cond_wn = WN_CAND ( if_cond_wn, temp_node );
12841 else
12842 if_cond_wn = temp_node;
12843
12844 #else // bug 7772
12845 if (if_cond_wn == NULL)
12846 if_cond_wn = WN_CreateIntconst(OPC_I4INTCONST, 1);
12847 temp_node = Gen_MP_Store(ok_to_fork_st, ok_to_fork_ofst, if_cond_wn);
12848 WN_INSERT_BlockLast( replace_block, temp_node );
12849
12850 WN *canfork_block = WN_CreateBlock ( );
12851 WN_INSERT_BlockLast( canfork_block, Gen_Can_Fork( ));
12852 GET_RETURN_PREGS(rreg1, rreg2, MTYPE_I4);
12853 temp_node = Gen_MP_Store( ok_to_fork_st, ok_to_fork_ofst,
12854 WN_LdidPreg( MTYPE_I4, rreg1 ));
12855 WN_linenum(temp_node) = line_number;
12856 WN_INSERT_BlockLast( canfork_block, temp_node );
12857
12858 temp_node = WN_CreateIf(Gen_MP_Load(ok_to_fork_st, ok_to_fork_ofst),
12859 canfork_block, WN_CreateBlock());
12860 WN_INSERT_BlockLast( replace_block, temp_node );
12861
12862 if_cond_wn = Gen_MP_Load(ok_to_fork_st, ok_to_fork_ofst);
12863 #endif
12864 }
12865
12866
12867 stmt2_block = serial_stmt_block;
12868
12869
12870
12871
12872
12873
12874 temp_node = WN_CreateIf ( if_cond_wn, stmt1_block, stmt2_block );
12875 WN_linenum(temp_node) = line_number;
12876
12877
12878
12879 if (!mp_if) {
12880
12881 }
12882
12883 WN_INSERT_BlockLast ( replace_block, temp_node );
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893 } else if (mpt == MPP_ORPHANED_PDO) {
12894
12895 Is_True(livein_block == NULL,
12896 ("non-NULL livein_block for MPP_ORPHANED_PDO"));
12897 Is_True(liveout_block == NULL,
12898 ("non-NULL liveout_block for MPP_ORPHANED_PDO"));
12899
12900 if (do_preamble_block)
12901 WN_INSERT_BlockLast ( replace_block, do_preamble_block );
12902 WN_INSERT_BlockLast ( replace_block, stmt_block );
12903
12904 }
12905
12906
12907
12908
12909 finish_processing:
12910
12911 while (affinity_nodes) {
12912 next_node = WN_next(affinity_nodes);
12913 WN_DELETE_Tree ( affinity_nodes );
12914 affinity_nodes = next_node;
12915 }
12916
12917 while (affinity_d_nodes) {
12918 next_node = WN_next(affinity_d_nodes);
12919 WN_DELETE_Tree ( affinity_d_nodes );
12920 affinity_d_nodes = next_node;
12921 }
12922
12923 while (affinity_t_nodes) {
12924 next_node = WN_next(affinity_t_nodes);
12925 WN_DELETE_Tree ( affinity_t_nodes );
12926 affinity_t_nodes = next_node;
12927 }
12928
12929 if (chunk_node)
12930 WN_DELETE_Tree ( chunk_node );
12931
12932 while (copyin_nodes) {
12933 next_node = WN_next(copyin_nodes);
12934 WN_DELETE_Tree ( copyin_nodes );
12935 copyin_nodes = next_node;
12936 }
12937
12938 if (if_node)
12939 WN_DELETE_Tree ( if_node );
12940
12941 while (lastlocal_nodes) {
12942 next_node = WN_next(lastlocal_nodes);
12943 WN_Delete ( lastlocal_nodes );
12944 lastlocal_nodes = next_node;
12945 }
12946
12947 while (firstprivate_nodes) {
12948 next_node = WN_next(firstprivate_nodes);
12949 WN_Delete ( firstprivate_nodes );
12950 firstprivate_nodes = next_node;
12951 }
12952
12953 if (lastthread_node)
12954 WN_Delete ( lastthread_node );
12955
12956 while (local_nodes) {
12957 next_node = WN_next(local_nodes);
12958 WN_Delete ( local_nodes );
12959 local_nodes = next_node;
12960 }
12961
12962 if (mpnum_node)
12963 WN_Delete ( mpnum_node );
12964
12965 if (mpsched_node)
12966 WN_Delete ( mpsched_node );
12967
12968 if (numthreads_node)
12969 WN_DELETE_Tree ( numthreads_node );
12970
12971 if (ordered_node)
12972 WN_Delete ( ordered_node );
12973
12974 while (reduction_nodes) {
12975 next_node = WN_next(reduction_nodes);
12976 WN_DELETE_Tree ( reduction_nodes );
12977 reduction_nodes = next_node;
12978 }
12979
12980 while (shared_nodes) {
12981 next_node = WN_next(shared_nodes);
12982 WN_Delete ( shared_nodes );
12983 shared_nodes = next_node;
12984 }
12985
12986 for (i=0; i < local_count; i++) {
12987 if (var_table[i].vtree)
12988 WN_DELETE_Tree ( var_table[i].vtree );
12989 if (var_table[i].vtreex)
12990 WN_DELETE_Tree ( var_table[i].vtreex );
12991 }
12992
12993
12994
12995 if (mp_if) {
12996
12997
12998
12999
13000 verify_mp_lowered.Set_replace_block(replace_block,
13001 WN_next(WN_last(replace_block)));
13002 return_nodes = replace_block;
13003
13004 } else {
13005
13006
13007
13008
13009 if (WN_first(replace_block)) {
13010 return_nodes = WN_first(replace_block);
13011 WN_next(WN_last(replace_block)) = cont_nodes;
13012 if (cont_nodes)
13013 WN_prev(cont_nodes) = WN_last(replace_block);
13014 } else
13015 return_nodes = cont_nodes;
13016
13017 WN_Delete ( replace_block );
13018 verify_mp_lowered.Set_replace_block(return_nodes, cont_nodes);
13019 }
13020
13021 return (return_nodes);
13022 }
13023
13024
13025
13026
13027
13028
13029
13030
13031 extern void
13032 LowerMP_PU_Init()
13033 {
13034 if (PU_Info_proc_sym(Current_PU_Info) != last_pu_proc_sym) {
13035 last_pu_proc_sym = PU_Info_proc_sym(Current_PU_Info);
13036 nl_idx = 0;
13037 do_id = 0;
13038 region_id = 0;
13039 lock_id = 0;
13040 if (mpid_size > 0)
13041 BZERO ( mpid_table, mpid_size * sizeof(MPID_TABLE) );
13042
13043
13044
13045 pu_chunk_node = NULL;
13046 pu_mpsched_node = NULL;
13047 Init_PU_Globals( );
13048
13049 }
13050 }
13051
13052 extern BOOL
13053 WN_has_pragma_with_side_effect ( WN *wn )
13054 {
13055 OPERATOR opr;
13056 opr = WN_operator(wn);
13057 FmtAssert (((opr == OPR_PRAGMA) || (opr == OPR_XPRAGMA)),
13058 ("WN must contain PRAGMA in WN_has_pragma_with_side_effect\n"));
13059 switch (WN_pragma(wn)) {
13060 case WN_PRAGMA_BARRIER:
13061 case WN_PRAGMA_CRITICAL_SECTION_BEGIN:
13062 case WN_PRAGMA_COPYIN:
13063 case WN_PRAGMA_ORDERED:
13064 case WN_PRAGMA_SINGLE_PROCESS_BEGIN:
13065 case WN_PRAGMA_MASTER_BEGIN:
13066 case WN_PRAGMA_FILL:
13067 case WN_PRAGMA_ALIGN:
13068 case WN_PRAGMA_INDEPENDENT_BEGIN:
13069 case WN_PRAGMA_ORDERED_BEGIN:
13070 case WN_PRAGMA_REDISTRIBUTE:
13071 case WN_PRAGMA_DISTRIBUTE:
13072 case WN_PRAGMA_ENTER_GATE:
13073 case WN_PRAGMA_PAGE_PLACE:
13074 return TRUE;
13075 default:
13076 return FALSE;
13077 }
13078 }