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,