00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #define __STDC_LIMIT_MACROS
00058 #include <stdint.h>
00059 #ifdef USE_PCH
00060 #include "common_com_pch.h"
00061 #endif
00062 #pragma hdrstop
00063 #include <math.h>
00064
00065 #include "defs.h"
00066 #include "stab.h"
00067 #include "irbdata.h"
00068 #include "wn.h"
00069 #include "config_targ.h"
00070 #include "wn_simp.h"
00071 #include "wio.h"
00072 #include "targ_const.h"
00073 #include "const.h"
00074 #include "strtab.h"
00075 #include "config.h"
00076 #ifdef BACK_END
00077 #include "fb_whirl.h"
00078 #include "tracing.h"
00079 #endif
00080
00081 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
00082 #include "wn_util.h"
00083 #endif
00084 #if !defined(FRONT_END_C) && !defined(IR_TOOLS) && defined(TARG_SL)
00085 #include "intrn_info.h"
00086 #endif
00087
00088 #ifdef KEEP_WHIRLSTATS
00089 INT32 whirl_num_allocated=0;
00090 INT32 whirl_bytes_allocated=0;
00091 INT32 whirl_num_deallocated=0;
00092 INT32 whirl_bytes_deallocated=0;
00093
00094 void whirlstats()
00095 {
00096 fprintf(stderr,"Num allocated = %d\nbytes allocated = %d\n",whirl_num_allocated,whirl_bytes_allocated);
00097 fprintf(stderr,"Num deallocated = %d\nbytes deallocated = %d\n",whirl_num_deallocated,whirl_bytes_deallocated);
00098 }
00099 #endif
00100
00101 MEM_POOL WN_mem_pool;
00102 MEM_POOL *WN_mem_pool_ptr = &WN_mem_pool;
00103 BOOL WN_mem_pool_initialized = FALSE;
00104
00105 typedef enum {
00106 UNKNOWN_TYPE, INT_TYPE, UINT_TYPE, FLOAT_TYPE, COMPLEX_TYPE
00107 } BTYPE;
00108
00109 static struct winfo {
00110 BTYPE base_type:8;
00111 BTYPE comp_type:8;
00112 INT size:16;
00113 } WINFO [MTYPE_LAST + 1] = {
00114 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00115 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00116 INT_TYPE, UINT_TYPE, 1,
00117 INT_TYPE, UINT_TYPE, 2,
00118 INT_TYPE, UINT_TYPE, 4,
00119 INT_TYPE, UINT_TYPE, 8,
00120 UINT_TYPE, INT_TYPE, 1,
00121 UINT_TYPE, INT_TYPE, 2,
00122 UINT_TYPE, INT_TYPE, 4,
00123 UINT_TYPE, INT_TYPE, 8,
00124 FLOAT_TYPE, FLOAT_TYPE, 4,
00125 FLOAT_TYPE, FLOAT_TYPE, 8,
00126 #ifdef TARG_IA64
00127 FLOAT_TYPE, FLOAT_TYPE, 16,
00128 #else
00129 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00130 #endif
00131 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00132 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00133 FLOAT_TYPE, FLOAT_TYPE, 16,
00134 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00135 COMPLEX_TYPE, COMPLEX_TYPE, 8,
00136 COMPLEX_TYPE, COMPLEX_TYPE, 16,
00137 COMPLEX_TYPE, COMPLEX_TYPE, 32,
00138 UNKNOWN_TYPE, UNKNOWN_TYPE, 0,
00139 INT_TYPE, UINT_TYPE, 0,
00140 UINT_TYPE, INT_TYPE, 4,
00141 UINT_TYPE, INT_TYPE, 8,
00142 COMPLEX_TYPE, COMPLEX_TYPE, 32,
00143 };
00144
00145 #define WTYPE_base_type(w) WINFO[w].base_type
00146 #define WTYPE_comp_type(w) WINFO[w].comp_type
00147 #define WTYPE_size(w) WINFO[w].size
00148
00149 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
00150
00151 BOOL FE_Address_Opt = TRUE;
00152 BOOL FE_Store_Opt = TRUE;
00153 BOOL FE_Cvtl_Opt = TRUE;
00154
00155 extern "C" { WN * WN_COPY_Tree ( WN * ); }
00156
00157 static UINT64 masks [] = { 0, 0xff, 0xffff, 0, 0xffffffffULL,
00158 0, 0, 0, 0xffffffffffffffffULL };
00159
00160 static WN *
00161 fe_combine_address_offset ( WN_OFFSET * offset, WN * addr )
00162 {
00163 WN * new_addr;
00164 INT64 const_val;
00165 INT32 i;
00166
00167 if ( FE_Address_Opt == FALSE )
00168 return addr;
00169
00170 i = -1;
00171 new_addr = addr;
00172
00173 if ( WN_operator(addr) == OPR_ADD
00174 || WN_operator(addr) == OPR_SUB ) {
00175
00176 if ( WN_operator(WN_kid0(addr)) == OPR_INTCONST )
00177 i = 0;
00178
00179 else
00180 if ( WN_operator(WN_kid1(addr)) == OPR_INTCONST )
00181 i = 1;
00182 }
00183
00184 if ( i >= 0 ) {
00185
00186 if ( WN_operator(addr) == OPR_ADD )
00187 const_val = *offset + WN_const_val(WN_kid(addr,i));
00188
00189 else
00190 const_val = *offset - WN_const_val(WN_kid(addr,i));
00191
00192 if ( const_val >= INT32_MIN && const_val <= INT32_MAX ) {
00193
00194 *offset = const_val;
00195 new_addr = WN_COPY_Tree ( WN_kid(addr,1-i) );
00196 }
00197 }
00198
00199 return new_addr;
00200 }
00201 #endif
00202
00203 BOOL
00204 Types_Are_Compatible ( TYPE_ID ltype, WN * wn )
00205 {
00206 TYPE_ID rtype = WN_rtype(wn);
00207 return ( ( WTYPE_base_type(ltype) == WTYPE_base_type(rtype) )
00208 || ( WTYPE_base_type(ltype) == WTYPE_comp_type(rtype) ) );
00209 }
00210
00211
00212
00213 BOOL
00214 IPO_Types_Are_Compatible ( TYPE_ID ltype, TYPE_ID rtype )
00215 {
00216 BOOL compatible;
00217
00218 #if 0
00219
00220
00221
00222
00223
00224
00225
00226 if ((WTYPE_base_type(ltype) == UINT_TYPE) &&
00227 (WTYPE_base_type(rtype) == INT_TYPE))
00228 return FALSE;
00229 #endif
00230
00231
00232
00233
00234 #ifdef KEY
00235 BOOL type_compatible = ((WTYPE_base_type(ltype) == WTYPE_base_type(rtype))
00236 || (WTYPE_base_type(ltype) == WTYPE_comp_type(rtype)));
00237 BOOL size_compatible = WTYPE_size(ltype) >= WTYPE_size(rtype);
00238
00239 compatible = type_compatible && size_compatible;
00240
00241 if (!compatible && type_compatible)
00242 {
00243
00244
00245 if (rtype == MTYPE_U4 || rtype == MTYPE_I4)
00246 compatible = TRUE;
00247 }
00248 #else
00249 compatible = (((WTYPE_base_type(ltype) == WTYPE_base_type(rtype))
00250 || (WTYPE_base_type(ltype) == WTYPE_comp_type(rtype)))
00251 && (WTYPE_size(ltype) >= WTYPE_size(rtype)));
00252 #endif // KEY
00253
00254 return (compatible);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 typedef WN * WN_FREE_LIST;
00285
00286
00287
00288
00289
00290
00291
00292 #define WN_FREE_LIST_Empty(list) (*(list) == NULL)
00293
00294
00295
00296
00297 static BOOL use_free_list = TRUE;
00298
00299 void
00300 Dont_Use_WN_Free_List (void)
00301 {
00302 use_free_list = FALSE;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 inline void WN_FREE_LIST_Push(WN_FREE_LIST *list, WN *wn)
00312 {
00313 STMT_WN *stmt_wn;
00314 stmt_wn = (STMT_WN *) WN_StartAddress(wn);
00315 WN_prev_free(stmt_wn) = (WN *)(*list);
00316 *list = (WN_FREE_LIST)stmt_wn;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 inline WN *WN_FREE_LIST_Pop(WN_FREE_LIST *list)
00328 {
00329 STMT_WN *item = (STMT_WN *)(*list);
00330 *list = (WN_FREE_LIST)WN_prev_free(item);
00331 return (WN *)item;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 WN_FREE_LIST free_stmt_list, free_expr_list;
00349
00350 inline WN_FREE_LIST *Which_WN_FREE_LIST(INT32 size)
00351 {
00352 if (size == sizeof(WN)+2*sizeof(WN *))
00353 return &free_stmt_list;
00354 else if (size == sizeof(WN))
00355 return &free_expr_list;
00356 return NULL;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 void WN_Mem_Push(void)
00370 {
00371 if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
00372 MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
00373 WN_mem_pool_initialized = TRUE;
00374 }
00375 MEM_POOL_Push(WN_mem_pool_ptr);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 void WN_Mem_Pop(void)
00389 {
00390 if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
00391 MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
00392 WN_mem_pool_initialized = TRUE;
00393 }
00394 free_stmt_list = free_expr_list = NULL;
00395 MEM_POOL_Pop(WN_mem_pool_ptr);
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 #define MAX_CLEANUP_FNS 8
00407 static void (*delete_cleanup_fns[MAX_CLEANUP_FNS])(WN *wn);
00408 static UINT16 num_delete_cleanup_fns = 0;
00409
00410 void IPA_WN_Delete(WN_MAP_TAB *maptab, WN *wn)
00411 {
00412 UINT16 i;
00413 WN_FREE_LIST *free_list;
00414
00415 Is_True((WN_opcode(wn)),("Trying to delete WHIRL node with 0 opcode"));
00416
00417 free_list = use_free_list ? Which_WN_FREE_LIST(WN_Size(wn)) : 0;
00418
00419
00420 #ifdef KEEP_WHIRLSTATS
00421 whirl_num_deallocated++;
00422 whirl_bytes_deallocated += WN_Size(wn);
00423 #endif
00424
00425
00426
00427 for (i = 0; i < num_delete_cleanup_fns; i++)
00428 (*delete_cleanup_fns[i])(wn);
00429
00430
00431
00432 if (free_list)
00433 WN_FREE_LIST_Push(free_list, wn);
00434
00435
00436 WN_MAP_Add_Free_List(maptab, wn);
00437
00438
00439
00440 WN_set_operator (wn, OPERATOR_UNKNOWN);
00441 WN_set_rtype (wn, MTYPE_UNKNOWN);
00442 WN_set_desc (wn, MTYPE_UNKNOWN);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 void IPA_WN_DELETE_Tree(WN_MAP_TAB *maptab, WN *tree)
00454 {
00455 WN *node;
00456 INT i;
00457
00458 if (tree) {
00459 if (WN_opcode(tree) == OPC_BLOCK) {
00460 node = WN_first(tree);
00461 while (node != NULL) {
00462 WN *next = WN_next(node);
00463 IPA_WN_DELETE_Tree (maptab, node);
00464 node = next;
00465 }
00466 } else
00467 for (i = 0; i < WN_kid_count(tree); i++)
00468 IPA_WN_DELETE_Tree(maptab, WN_kid(tree, i));
00469
00470 IPA_WN_Delete(maptab, tree);
00471 }
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 void WN_Register_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
00483 {
00484 UINT16 i;
00485 for (i=0; i < num_delete_cleanup_fns; i++)
00486 if (delete_cleanup_fns[i] == cleanup_fn)
00487 return;
00488 FmtAssert(num_delete_cleanup_fns < MAX_CLEANUP_FNS,
00489 ("attempting to register too many WN_Delete cleanup functions"));
00490 delete_cleanup_fns[num_delete_cleanup_fns++] = cleanup_fn;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 void WN_Remove_Delete_Cleanup_Function(void (*cleanup_fn)(WN *wn))
00502 {
00503 UINT16 i;
00504
00505 for (i = 0; i < num_delete_cleanup_fns; i++)
00506 if (delete_cleanup_fns[i] == cleanup_fn)
00507 break;
00508 if (i >= num_delete_cleanup_fns)
00509 return;
00510 --num_delete_cleanup_fns;
00511 for (; i < num_delete_cleanup_fns; i++)
00512 delete_cleanup_fns[i] = delete_cleanup_fns[i+1];
00513 }
00514
00515 #ifdef KEY // bug 9651
00516 void WN_Reset_Num_Delete_Cleanup_Fns(void)
00517 {
00518 num_delete_cleanup_fns = 0;
00519 }
00520 #endif
00521
00522
00523
00524
00525
00526
00527
00528 #define New_Map_Id() ((WN_MAP_ID) (-1))
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 WN *
00539 WN_Create (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, mINT16 kid_count)
00540 {
00541 OPCODE opcode = OPCODE_make_op (opr, rtype, desc);
00542 INT16 next_prev_ptrs = (OPCODE_has_next_prev(opcode) ? 1 : 0);
00543 INT16 size = (sizeof(WN) +
00544 (sizeof(WN *) * (MAX(0,kid_count-2))) +
00545 next_prev_ptrs * (sizeof(mUINT64) + (2 * sizeof(WN *))));
00546 WN_FREE_LIST *free_list;
00547 WN *wn;
00548
00549 free_list = use_free_list ? Which_WN_FREE_LIST(size) : 0;
00550
00551 #ifdef KEEP_WHIRLSTATS
00552 whirl_num_allocated++;
00553 whirl_bytes_allocated += size;
00554 #endif
00555
00556 Is_True(((OPCODE_nkids(opcode) == kid_count) ||
00557 (OPCODE_nkids(opcode) == -1)),
00558 ("Illegal number of kids for WN_Create"));
00559
00560
00561
00562
00563
00564
00565 if (free_list && !WN_FREE_LIST_Empty(free_list)) {
00566 wn = WN_FREE_LIST_Pop(free_list);
00567 BZERO(wn, size);
00568 } else {
00569 if (WN_mem_pool_ptr == &WN_mem_pool && !WN_mem_pool_initialized) {
00570 MEM_POOL_Initialize(WN_mem_pool_ptr, "WHIRL Nodes", TRUE);
00571 MEM_POOL_Push(WN_mem_pool_ptr);
00572 WN_mem_pool_initialized = TRUE;
00573 }
00574 wn = (WN *)MEM_POOL_Alloc(WN_mem_pool_ptr, size);
00575 BZERO(wn, size);
00576 }
00577
00578
00579
00580 if (next_prev_ptrs) {
00581 STMT_WN *stmt_wn;
00582 stmt_wn = (STMT_WN *)wn;
00583 wn = (WN *)&(WN_real_fields(stmt_wn));
00584 }
00585
00586
00587
00588 WN_set_operator(wn, opr);
00589 WN_set_rtype(wn, rtype);
00590 WN_set_desc(wn, desc);
00591 WN_set_kid_count(wn, kid_count);
00592 WN_set_map_id(wn, New_Map_Id());
00593
00594 return wn;
00595 }
00596
00597 WN *
00598 WN_Create_Generic (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
00599 mINT16 kid_count, WN *next, WN *prev,
00600 ST_IDX st,INT32 label_number, INT32 num_entries,
00601 TY_IDX ty, TY_IDX load_addr_ty, WN_OFFSET offset,
00602 INT16 cvtl_bits, INT32 ,
00603 WN_ESIZE element_size, INT64 const_value, UINT32 flag,
00604 INTRINSIC intrinsic)
00605 {
00606 OPCODE opcode = OPCODE_make_op (opr, rtype, desc);
00607 WN *wn;
00608
00609
00610 wn = WN_Create(opcode,kid_count);
00611 if (OPCODE_has_next_prev(opcode)) {
00612 WN_next(wn) = next;
00613 WN_prev(wn) = prev;
00614 }
00615 if (OPCODE_has_sym(opcode)) {
00616 WN_st_idx(wn) = st;
00617 }
00618 if (OPCODE_has_label(opcode)) {
00619 WN_label_number(wn) = label_number;
00620 }
00621 if (OPCODE_has_num_entries(opcode)) {
00622 WN_num_entries(wn) = num_entries;
00623 }
00624 if (OPCODE_has_1ty(opcode)) {
00625 WN_set_ty(wn,ty);
00626 }
00627 if (OPCODE_has_2ty(opcode)) {
00628 WN_set_ty(wn,ty);
00629 WN_set_load_addr_ty(wn,load_addr_ty);
00630 }
00631 if (OPCODE_has_offset(opcode)) {
00632 WN_offset(wn) = offset;
00633 }
00634 if (OPCODE_has_bits(opcode)) {
00635 WN_cvtl_bits(wn) = cvtl_bits;
00636 }
00637
00638 #if 0
00639 if (OPCODE_has_ndim(opcode)) {
00640 WN_num_dim(wn) = num_dim;
00641 }
00642 #endif
00643 if (OPCODE_has_esize(opcode)) {
00644 WN_element_size(wn) = element_size;
00645 }
00646 if (OPCODE_has_value(opcode)) {
00647 WN_const_val(wn) = const_value;
00648 }
00649 if (OPCODE_has_flags(opcode)) {
00650 WN_set_flag(wn,flag);
00651 }
00652 if (OPCODE_has_inumber(opcode)) {
00653 WN_intrinsic(wn) = intrinsic;
00654 }
00655 return wn;
00656 }
00657
00658
00659
00660
00661 BOOL WN_Equiv(WN *wn1, WN *wn2)
00662 {
00663 OPCODE opcode;
00664
00665 opcode = WN_opcode(wn1);
00666 if (opcode != WN_opcode(wn2)) return(FALSE);
00667 if (opcode == OPC_BLOCK) return(TRUE);
00668 if (WN_kid_count(wn1) != WN_kid_count(wn2)) return(FALSE);
00669
00670 if (OPCODE_has_sym(opcode)) {
00671 if (WN_st_idx(wn1) != WN_st_idx(wn2)) return(FALSE);
00672 }
00673 if (OPCODE_has_label(opcode)) {
00674 if (WN_label_number(wn1) != WN_label_number(wn2)) return(FALSE);
00675 }
00676 if (OPCODE_has_num_entries(opcode)) {
00677 if (WN_num_entries(wn1) != WN_num_entries(wn2)) return(FALSE);
00678 }
00679 if (OPCODE_has_1ty(opcode)) {
00680 if (WN_ty(wn1) != WN_ty(wn2)) return(FALSE);
00681 }
00682 if (OPCODE_has_2ty(opcode)) {
00683 if (WN_ty(wn1) != WN_ty(wn2)) return(FALSE);
00684 if (WN_load_addr_ty(wn1) != WN_load_addr_ty(wn2)) return(FALSE);
00685 }
00686 if (OPCODE_has_offset(opcode)) {
00687 if (WN_offset(wn1) != WN_offset(wn2)) return(FALSE);
00688 }
00689 if (OPCODE_has_bits(opcode)) {
00690 if (WN_cvtl_bits(wn1) != WN_cvtl_bits(wn2)) return(FALSE);
00691 }
00692 if (OPCODE_has_ndim(opcode)) {
00693 if (WN_num_dim(wn1) != WN_num_dim(wn2)) return(FALSE);
00694 }
00695 if (OPCODE_has_esize(opcode)) {
00696 if (WN_element_size(wn1) != WN_element_size(wn2)) return(FALSE);
00697 }
00698 if (OPCODE_has_value(opcode)) {
00699 if (WN_const_val(wn1) != WN_const_val(wn2)) return(FALSE);
00700 }
00701 if (OPCODE_has_flags(opcode)) {
00702 if (WN_flag(wn1) != WN_flag(wn2)) return(FALSE);
00703 }
00704 if (OPCODE_has_inumber(opcode)) {
00705 if (WN_intrinsic(wn1) != WN_intrinsic(wn2)) return(FALSE);
00706 }
00707
00708 return(TRUE);
00709 }
00710
00711
00712
00713
00714
00715
00716
00717 WN *WN_CreateBlock(void)
00718 {
00719 WN *wn;
00720
00721 wn = WN_Create(OPC_BLOCK,0);
00722 WN_first(wn) = WN_last(wn) = NULL;
00723 return(wn);
00724 }
00725
00726 WN *WN_CreateDO(WN *index, WN *start, WN *end, WN *step, WN *body, WN *loop_info)
00727 {
00728 WN *wn;
00729 INT nkids = 5;
00730 if (loop_info != NULL) nkids++;
00731
00732 Is_True(OPCODE_is_stmt(WN_opcode(start)),("Bad start in WN_CreateDO"));
00733 Is_True(OPCODE_is_stmt(WN_opcode(step)),("Bad step in WN_CreateDO"));
00734 Is_True(loop_info == NULL || WN_opcode(loop_info) == OPC_LOOP_INFO,
00735 ("Bad loop_info in WN_CreateDO"));
00736
00737
00738
00739
00740 Is_True(WN_opcode(body) == OPC_BLOCK,("Bad body in WN_CreateDO"));
00741
00742 wn = WN_Create(OPC_DO_LOOP,nkids);
00743 WN_index(wn) = index;
00744 WN_start(wn) = start;
00745 WN_end(wn) = end;
00746 WN_step(wn) = step;
00747 WN_do_body(wn) = body;
00748 if (loop_info) WN_set_do_loop_info(wn, loop_info);
00749
00750 return(wn);
00751 }
00752
00753 WN *WN_CreateDoWhile(WN *test, WN *body)
00754 {
00755 WN *wn;
00756
00757 Is_True(WN_opcode(body) == OPC_BLOCK, ("Bad body in WN_CreateDoWhile"));
00758
00759
00760
00761
00762 wn = WN_Create(OPC_DO_WHILE,2);
00763 WN_while_test(wn) = test;
00764 WN_while_body(wn) = body;
00765
00766 return(wn);
00767 }
00768
00769 WN *WN_CreateWhileDo(WN *test, WN *body)
00770 {
00771 WN *wn;
00772
00773 Is_True(WN_opcode(body) == OPC_BLOCK, ("Bad body in WN_CreateWhileDo"));
00774
00775
00776
00777
00778 wn = WN_Create(OPC_WHILE_DO,2);
00779 WN_while_test(wn) = test;
00780 WN_while_body(wn) = body;
00781
00782 return(wn);
00783 }
00784
00785 WN *WN_CreateIf(WN *test, WN *if_then, WN *if_else)
00786 {
00787 WN *wn;
00788
00789 Is_True(WN_opcode(if_then) == OPC_BLOCK, ("Bad then in WN_CreateIf"));
00790 Is_True(WN_opcode(if_else) == OPC_BLOCK, ("Bad else in WN_CreateIf"));
00791
00792
00793
00794
00795 wn = WN_Create(OPC_IF,3);
00796 WN_if_test(wn) = test;
00797 WN_then(wn) = if_then;
00798 WN_else(wn) = if_else;
00799
00800 WN_Reset_If_Guard(wn);
00801 return(wn);
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811 static WN *WN_block_element(WN *element)
00812 {
00813 if (element == NULL || WN_opcode(element) != OPC_BLOCK) {
00814 WN *block = WN_CreateBlock();
00815 if (element != NULL) {
00816 WN_first(block) = element;
00817 WN_last (block) = element;
00818 WN_prev(element) = NULL;
00819 WN_next(element) = NULL;
00820 }
00821 return block;
00822 } else
00823 return element;
00824 }
00825
00826 static INT32 last_region_id = 0;
00827
00828 extern "C" INT32
00829 New_Region_Id(void)
00830 {
00831 return ++last_region_id;
00832 }
00833 extern "C" INT32
00834 Last_Region_Id(void)
00835 {
00836 return last_region_id;
00837 }
00838
00839
00840
00841 extern void
00842 Set_Max_Region_Id (INT id)
00843 {
00844 if (id == 0)
00845 last_region_id = 0;
00846 else
00847 last_region_id = MAX(last_region_id,id);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 WN *
00872 WN_CreateRegion (REGION_KIND kind, WN *body, WN *pragmas, WN *exits,
00873 INT region_id, INITO_IDX ereg_supp)
00874 {
00875 WN *wn;
00876
00877 Is_True( OPCODE_is_scf(WN_opcode(body)) , ("Bad body in WN_CreateRegion"));
00878 wn = WN_Create(OPC_REGION,3);
00879 WN_Set_Linenum(wn,WN_Get_Linenum(body));
00880
00881 WN_set_region_kind(wn, kind);
00882 WN_set_region_id(wn, (region_id == -1) ? New_Region_Id() : region_id);
00883 WN_region_body(wn) = WN_block_element(body);
00884 WN_region_pragmas(wn) = WN_block_element(pragmas);
00885 WN_region_exits(wn) = WN_block_element(exits);
00886 WN_ereg_supp(wn) = ereg_supp;
00887
00888 Set_PU_has_region (Get_Current_PU ());
00889
00890 return(wn);
00891 }
00892
00893 WN *WN_CreateRegionExit (INT32 label_number)
00894 {
00895 WN *wn;
00896
00897 wn = WN_Create(OPC_REGION_EXIT,0);
00898 WN_label_number(wn) = label_number;
00899
00900 return(wn);
00901 }
00902
00903
00904 WN *
00905 WN_CreateEntry (INT16 nkids, ST_IDX name, WN *body, WN *pragmas, WN *varrefs)
00906 {
00907 WN *wn;
00908 wn = WN_Create (OPC_FUNC_ENTRY, nkids + 3);
00909 WN_entry_name(wn) = name;
00910 WN_func_body(wn) = body;
00911 WN_func_pragmas(wn) = WN_block_element(pragmas);
00912 WN_func_varrefs(wn) = WN_block_element(varrefs);
00913 return wn;
00914 }
00915
00916
00917
00918
00919
00920
00921 #if defined(TARG_SL) //fork_joint
00922 WN *WN_CreateFork(INT32 label_number, BOOL major)
00923 {
00924 WN *wn;
00925 wn = WN_Create(major ? OPC_SL2_FORK_MAJOR : OPC_SL2_FORK_MINOR , 0);
00926 WN_label_number(wn) = label_number;
00927 return(wn);
00928 }
00929 #endif
00930
00931
00932 WN *WN_CreateGoto(INT32 label_number)
00933 {
00934 WN *wn;
00935
00936 wn = WN_Create(OPC_GOTO,0);
00937 WN_label_number(wn) = label_number;
00938
00939 return(wn);
00940 }
00941
00942 WN *WN_CreateGotoOuterBlock (INT32 label_number, SYMTAB_IDX label_level)
00943 {
00944 WN * wn;
00945 wn = WN_Create(OPC_GOTO_OUTER_BLOCK, 0);
00946 WN_label_number(wn) = label_number;
00947 WN_label_level(wn) = label_level;
00948
00949 return wn;
00950 }
00951
00952 WN *WN_CreateAgoto(WN *addr)
00953 {
00954 WN *wn;
00955
00956 Is_True(MTYPE_byte_size(WN_rtype(addr)) == MTYPE_byte_size(Pointer_type),
00957 ("Bad addr in WN_CreateAgoto"));
00958 wn = WN_Create(OPC_AGOTO,1);
00959 WN_kid0(wn) = addr;
00960
00961 return(wn);
00962 }
00963
00964 WN *WN_CreateAltentry(ST_IDX entry)
00965 {
00966 WN *wn;
00967
00968 wn = WN_Create(OPC_ALTENTRY,0);
00969 WN_st_idx(wn) = entry;
00970
00971 return(wn);
00972 }
00973
00974 WN *WN_CreateTruebr(INT32 label_number, WN *exp)
00975 {
00976 WN *wn;
00977
00978 Is_True(OPCODE_is_expression(WN_opcode(exp)),
00979 ("Bad exp in WN_CreateTruebr"));
00980 wn = WN_Create(OPC_TRUEBR,1);
00981 WN_kid0(wn) = exp;
00982 WN_label_number(wn) = label_number;
00983
00984 return(wn);
00985 }
00986
00987 WN *WN_CreateFalsebr(INT32 label_number, WN *exp)
00988 {
00989 WN *wn;
00990
00991 Is_True(OPCODE_is_expression(WN_opcode(exp)),
00992 ("Bad exp in WN_CreateFalsebr"));
00993 wn = WN_Create(OPC_FALSEBR,1);
00994 WN_kid0(wn) = exp;
00995 WN_label_number(wn) = label_number;
00996
00997 return(wn);
00998 }
00999
01000
01001 WN *WN_CreateReturn(void)
01002 {
01003 WN *wn;
01004
01005 wn = WN_Create(OPC_RETURN,0);
01006
01007 return(wn);
01008 }
01009
01010 WN *WN_CreateReturn_Val (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, WN *val)
01011 {
01012 WN *wn;
01013
01014 wn = WN_Create (opr, rtype, desc, 1);
01015 WN_kid0(wn) = val;
01016
01017 return(wn);
01018 }
01019
01020 WN *
01021 WN_CreateLabel (
01022 INT32 label_number, UINT32 label_flag, WN *loop_info)
01023 {
01024 WN *wn;
01025 INT nkids = 0;
01026 if (loop_info != NULL) nkids++;
01027 Is_True(loop_info == NULL || WN_opcode(loop_info) == OPC_LOOP_INFO,
01028 ("Bad loop_info in WN_CreateDO"));
01029
01030 wn = WN_Create(OPC_LABEL, nkids);
01031 WN_label_number(wn) = label_number;
01032 WN_label_flag(wn) = label_flag;
01033 if ( loop_info )
01034 WN_set_label_loop_info(wn, loop_info);
01035
01036 return(wn);
01037 }
01038
01039 WN *WN_CreateCompgoto(INT32 num_entries, WN *value,
01040 WN *block, WN *deflt, INT32 last_label)
01041 {
01042 WN *wn;
01043
01044 Is_True(OPCODE_is_expression(WN_opcode(value)),
01045 ("Bad value in WN_CreateCompgoto"));
01046 Is_True(WN_opcode(block) == OPC_BLOCK,
01047 ("Bad block in WN_CreateCompgoto"));
01048 if (deflt) Is_True(WN_opcode(deflt) == OPC_GOTO,
01049 ("Bad deflt in WN_CreateCompgoto"));
01050 if (deflt) {
01051 wn = WN_Create(OPC_COMPGOTO,3);
01052 } else {
01053 wn = WN_Create(OPC_COMPGOTO,2);
01054 }
01055 WN_kid0(wn) = value;
01056 WN_kid(wn,1) = block;
01057 if (deflt) WN_kid(wn,2) = deflt;
01058 WN_num_entries(wn) = num_entries;
01059 WN_last_label(wn) = last_label;
01060
01061 return(wn);
01062 }
01063
01064 WN *WN_CreateSwitch(INT32 num_entries, WN *value,
01065 WN *block, WN *deflt, INT32 last_label)
01066 {
01067 WN *wn;
01068
01069 Is_True(OPCODE_is_expression(WN_opcode(value)),
01070 ("Bad value in WN_CreateSwitch"));
01071 Is_True(WN_opcode(block) == OPC_BLOCK,
01072 ("Bad block in WN_CreateSwitch"));
01073 if (deflt) Is_True(WN_opcode(deflt) == OPC_GOTO,
01074 ("Bad deflt in WN_CreateSwitch"));
01075 if (deflt) {
01076 wn = WN_Create(OPC_SWITCH,3);
01077 } else {
01078 wn = WN_Create(OPC_SWITCH,2);
01079 }
01080 WN_switch_test(wn) = value;
01081 WN_switch_table(wn) = block;
01082 if (deflt) WN_switch_default(wn) = deflt;
01083 WN_num_entries(wn) = num_entries;
01084 WN_last_label(wn) = last_label;
01085
01086 #ifdef FRONT_END
01087 Set_PU_has_very_high_whirl (Get_Current_PU ());
01088 #endif
01089
01090 return(wn);
01091 }
01092
01093 WN *WN_CreateCasegoto (INT64 case_value, INT32 case_label)
01094 {
01095 WN *wn;
01096 wn = WN_Create(OPC_CASEGOTO,0);
01097 WN_const_val(wn) = case_value;
01098 WN_label_number(wn) = case_label;
01099 return wn;
01100 }
01101
01102 WN *WN_CreateXgoto(INT32 num_entries, WN *value, WN *block, ST_IDX st)
01103 {
01104 WN *wn;
01105
01106 Is_True(OPCODE_is_expression(WN_opcode(value)),
01107 ("Bad value in WN_CreateXgoto"));
01108 Is_True(WN_opcode(block) == OPC_BLOCK,
01109 ("Bad block in WN_CreateXgoto"));
01110 wn = WN_Create(OPC_XGOTO,2);
01111 WN_kid0(wn) = value;
01112 WN_kid(wn,1) = block;
01113 WN_st_idx(wn) = st;
01114 WN_num_entries(wn) = num_entries;
01115
01116 return(wn);
01117 }
01118
01119 WN *
01120 WN_CreateIstore (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01121 WN_OFFSET offset, TY_IDX ty, WN *value, WN *addr,
01122 UINT field_id)
01123 {
01124 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01125 WN *wn;
01126 Is_True(MTYPE_is_pointer(WN_rtype(addr)) ||
01127 WN_rtype(addr)==MTYPE_U8 ||
01128 WN_rtype(addr)==MTYPE_U4 ||
01129 WN_rtype(addr)==MTYPE_I8 ||
01130 WN_rtype(addr)==MTYPE_I4,
01131 ("Bad addr in WN_CreateIstore"));
01132 Is_True(OPCODE_is_expression(WN_opcode(value)),
01133 ("Bad value in WN_CreateIstore"));
01134 Is_True(Types_Are_Compatible(OPCODE_desc(opc),value),
01135 ("Bad return type in WN_CreateIstore"));
01136 Is_True(opr == OPR_ISTORE || opr == OPR_ISTBITS,
01137 ("Bad opcode in WN_CreateIstore"));
01138
01139 #ifdef FRONT_END
01140 if (desc == MTYPE_M) {
01141 Set_PU_has_very_high_whirl (Get_Current_PU ());
01142 }
01143 #endif
01144
01145 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
01146
01147 addr = fe_combine_address_offset ( &offset, addr );
01148
01149 UINT64 ty_size;
01150 if (field_id == 0) {
01151 ty_size = TY_size(TY_pointed(ty));
01152 }
01153 else {
01154 UINT tmp = 0;
01155 ty_size = TY_size(FLD_type(FLD_get_to_field(TY_pointed(ty),field_id,tmp)));
01156 }
01157
01158 if ( FE_Cvtl_Opt ) {
01159
01160 OPCODE value_opc;
01161
01162 value_opc = WN_opcode(value);
01163
01164 if ( ( ( WN_operator(value) == OPR_CVTL
01165 || WN_operator(value) == OPR_CVT )
01166 && WN_cvtl_bits(value) == ty_size * 8 )
01167 || ( ( value_opc == OPC_I4I8CVT
01168 || value_opc == OPC_I4U8CVT
01169 || value_opc == OPC_U4I8CVT
01170 || value_opc == OPC_U4U8CVT )
01171 && ty_size < 8 ) )
01172 value = WN_kid0(value);
01173 }
01174
01175 if ( FE_Store_Opt
01176 && WN_operator(value) == OPR_BAND ) {
01177
01178 UINT64 mask;
01179 WN * kid0;
01180 WN * kid1;
01181
01182 mask = masks [ty_size];
01183 kid0 = WN_kid0(value);
01184 kid1 = WN_kid1(value);
01185
01186 if ( WN_operator(kid0) == OPR_INTCONST
01187 && ( ( WN_const_val(kid0) & mask ) == mask ) )
01188 value = kid1;
01189
01190 else
01191 if ( WN_operator(kid1) == OPR_INTCONST
01192 && ( ( WN_const_val(kid1) & mask ) == mask ) )
01193 value = kid0;
01194 }
01195 #endif
01196
01197 wn = WN_SimplifyIstore(opc,offset,ty,field_id,value,addr);
01198
01199 if (!wn) {
01200 wn = WN_Create(opc,2);
01201 WN_kid0(wn) = value;
01202 WN_kid1(wn) = addr;
01203 WN_store_offset(wn) = offset;
01204 WN_set_ty(wn,ty);
01205 WN_set_field_id(wn, field_id);
01206 }
01207 else {
01208
01209 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01210 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01211 }
01212 }
01213
01214 return(wn);
01215 }
01216
01217 WN *
01218 WN_CreateIstorex (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01219 TY_IDX ty, WN *value, WN *addr1, WN *addr2)
01220 {
01221 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01222 WN *wn;
01223
01224 Is_True(OPCODE_operator(opc) == OPR_ISTOREX,
01225 ("Bad opcode in WN_CreateIstorex"));
01226 Is_True(OPCODE_is_expression(WN_opcode(value)),
01227 ("Bad value in WN_CreateIstorex"));
01228 Is_True(WN_operator_is(addr1, OPR_LDID),
01229 ("Bad address 1 in WN_CreateIstorex"));
01230 Is_True(WN_operator_is(addr2, OPR_LDID),
01231 ("Bad address 2 in WN_CreateIstorex"));
01232 wn = WN_Create (opr, rtype, desc, 3);
01233 WN_store_offset(wn) = 0;
01234 WN_kid0(wn) = value;
01235 WN_kid1(wn) = addr1;
01236 WN_kid(wn,2) = addr2;
01237 WN_set_ty(wn,ty);
01238 return(wn);
01239 }
01240
01241 WN *WN_CreatePrefetchx(UINT32 flag, WN *addr1, WN *addr2)
01242 {
01243 WN *wn;
01244
01245 Is_True(WN_operator_is(addr1, OPR_LDID),
01246 ("Bad address 1 in WN_CreatePrefetchx"));
01247 Is_True(WN_operator_is(addr2, OPR_LDID),
01248 ("Bad address 2 in WN_CreatePrefetchx"));
01249 wn = WN_Create(OPC_PREFETCHX,2);
01250 WN_kid0(wn) = addr1;
01251 WN_kid1(wn) = addr2;
01252 WN_set_flag(wn,flag);
01253 return(wn);
01254 }
01255
01256 WN *WN_CreateMstore(WN_OFFSET offset, TY_IDX ty,
01257 WN *value, WN *addr, WN *num_bytes)
01258 {
01259 WN *wn;
01260
01261 Is_True(MTYPE_is_pointer(WN_rtype(addr)) ||
01262 WN_rtype(addr)==MTYPE_U8 ||
01263 WN_rtype(addr)==MTYPE_U4 ||
01264 WN_rtype(addr)==MTYPE_I8 ||
01265 WN_rtype(addr)==MTYPE_I4,
01266 ("Bad addr in WN_CreateMstore"));
01267 Is_True(OPCODE_is_expression(WN_opcode(value)),
01268 ("Bad value in WN_CreateMstore"));
01269 Is_True(OPCODE_is_expression(WN_opcode(num_bytes)),
01270 ("Bad num_bytes in WN_CreateMstore"));
01271
01272 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
01273
01274 addr = fe_combine_address_offset ( &offset, addr );
01275
01276 #endif
01277
01278 wn = WN_Create(OPC_MSTORE,3);
01279 WN_kid0(wn) = value;
01280 WN_kid1(wn) = addr;
01281 WN_kid(wn,2) = num_bytes;
01282 WN_store_offset(wn) = offset;
01283 WN_set_ty(wn,ty);
01284
01285 #ifdef FRONT_END
01286 Set_PU_has_very_high_whirl (Get_Current_PU ());
01287 #endif
01288 return(wn);
01289 }
01290
01291
01292
01293 WN *
01294 WN_CreateStid (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01295 WN_OFFSET offset, ST* st, TY_IDX ty, WN *value, UINT field_id)
01296 {
01297 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01298 WN *wn;
01299 ST_IDX st_idx = ST_st_idx (st);
01300
01301 Is_True(OPCODE_is_expression(WN_opcode(value)),
01302 ("Bad value in WN_CreateStid"));
01303 #ifndef KEY // g++ can create cases where the actual parameter to a
01304
01305 Is_True(Types_Are_Compatible(OPCODE_desc(opc),value),
01306 ("Bad return type in WN_CreateStid"));
01307 #endif
01308 Is_True(opr == OPR_STID || opr == OPR_STBITS,
01309 ("Bad opcode in WN_CreateStid"));
01310 #ifdef FRONT_END
01311 Is_True(!((offset == 0) && (st == Int32_Preg ||
01312 st == Int64_Preg ||
01313 st == Float32_Preg ||
01314 st == Float64_Preg)),
01315 ("Preg offset 0 in WN_CreateStid"));
01316 #endif
01317
01318 #ifdef FRONT_END
01319 if (desc == MTYPE_M && CURRENT_SYMTAB > GLOBAL_SYMTAB) {
01320 Set_PU_has_very_high_whirl (Get_Current_PU ());
01321 }
01322 #endif
01323
01324 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
01325
01326 UINT64 ty_size;
01327 if (field_id == 0) {
01328 ty_size = TY_size(ty);
01329 }
01330 else {
01331 UINT tmp = 0;
01332 ty_size = TY_size(FLD_type(FLD_get_to_field(ty, field_id, tmp)));
01333 }
01334
01335 if (FE_Cvtl_Opt && ST_class(st) != CLASS_PREG ) {
01336
01337 OPCODE value_opc;
01338
01339 value_opc = WN_opcode(value);
01340
01341 if ( ( ( WN_operator(value) == OPR_CVTL
01342 || WN_operator(value) == OPR_CVT )
01343 && WN_cvtl_bits(value) == ty_size * 8 )
01344 || ( ( value_opc == OPC_I4I8CVT
01345 || value_opc == OPC_I4U8CVT
01346 || value_opc == OPC_U4I8CVT
01347 || value_opc == OPC_U4U8CVT )
01348 && ty_size < 8 ) )
01349 value = WN_kid0(value);
01350 }
01351
01352 if (FE_Store_Opt && ST_class(st) != CLASS_PREG &&
01353 WN_operator(value) == OPR_BAND ) {
01354
01355 UINT64 mask;
01356 WN * kid0;
01357 WN * kid1;
01358
01359 mask = masks [ty_size];
01360 kid0 = WN_kid0(value);
01361 kid1 = WN_kid1(value);
01362
01363 if ( WN_operator(kid0) == OPR_INTCONST
01364 && ( ( WN_const_val(kid0) & mask ) == mask ) )
01365 value = kid1;
01366
01367 else
01368 if ( WN_operator(kid1) == OPR_INTCONST
01369 && ( ( WN_const_val(kid1) & mask ) == mask ) )
01370 value = kid0;
01371 }
01372
01373 #endif
01374 #ifdef TARG_NVISA
01375 if ((MTYPE_byte_size(desc) == 8 && MTYPE_byte_size(WN_rtype(value)) == 4)
01376 || (MTYPE_byte_size(desc) == 4 && MTYPE_byte_size(WN_rtype(value)) == 8))
01377 {
01378
01379
01380
01381
01382 DevWarn("insert cvt of stid, %d %d", desc, WN_rtype(value));
01383 value = WN_Cvt(WN_rtype(value), desc, value);
01384 }
01385 #endif
01386
01387 wn = WN_Create(opc,1);
01388 WN_kid0(wn) = value;
01389 WN_store_offset(wn) = offset;
01390 WN_st_idx(wn) = st_idx;
01391 WN_set_ty(wn,ty);
01392 WN_set_field_id(wn, field_id);
01393
01394 return(wn);
01395 }
01396
01397 WN *WN_CreatePrefetch(WN_OFFSET offset, UINT32 flag, WN *addr)
01398 {
01399 WN *wn;
01400 Is_True(MTYPE_is_pointer(WN_rtype(addr)),
01401 ("Bad addr in WN_CreatePrefetch"));
01402 wn = WN_Create(OPC_PREFETCH,1);
01403 WN_kid0(wn) = addr;
01404 WN_offset(wn) = offset;
01405 WN_set_flag(wn,flag);
01406 return(wn);
01407 }
01408
01409 WN *WN_CreateIo(IOSTATEMENT iostatement, mINT16 kid_count)
01410 {
01411 WN *wn;
01412
01413 Is_True(kid_count >= 1,("Bad kid_count in WN_CreateIo"));
01414 wn = WN_Create(OPC_IO,kid_count);
01415 WN_io_statement(wn) = iostatement;
01416 WN_Set_IO_Library(wn,target_io_library);
01417
01418 return(wn);
01419 }
01420
01421 WN *WN_CreateIoItem0(IOITEM ioitem, TY_IDX ty)
01422 {
01423 WN *wn;
01424
01425 wn = WN_Create(OPC_IO_ITEM,0);
01426 WN_io_item(wn) = ioitem;
01427 WN_set_ty(wn, ty);
01428
01429 return(wn);
01430 }
01431
01432 WN *WN_CreateIoItem1(IOITEM ioitem, WN *kid0, TY_IDX ty)
01433 {
01434 WN *wn;
01435
01436 wn = WN_Create(OPC_IO_ITEM,1);
01437 WN_io_item(wn) = ioitem;
01438 WN_kid0(wn) = kid0;
01439 WN_set_ty(wn, ty);
01440
01441 return(wn);
01442 }
01443
01444 WN *WN_CreateIoItem2(IOITEM ioitem, WN *kid0, WN *kid1, TY_IDX ty)
01445 {
01446 WN *wn;
01447
01448 wn = WN_Create(OPC_IO_ITEM,2);
01449 WN_io_item(wn) = ioitem;
01450 WN_kid0(wn) = kid0;
01451 WN_kid1(wn) = kid1;
01452 WN_set_ty(wn, ty);
01453
01454 return(wn);
01455 }
01456
01457 WN *WN_CreateIoItem3(IOITEM ioitem, WN *kid0, WN *kid1, WN *kid2, TY_IDX ty)
01458 {
01459 WN *wn;
01460
01461 wn = WN_Create(OPC_IO_ITEM,3);
01462 WN_io_item(wn) = ioitem;
01463 WN_kid0(wn) = kid0;
01464 WN_kid1(wn) = kid1;
01465 WN_kid(wn,2) = kid2;
01466 WN_set_ty(wn, ty);
01467
01468 return(wn);
01469 }
01470
01471 WN *WN_CreateIoItemN(IOITEM ioitem, mINT16 kid_count, TY_IDX ty)
01472 {
01473 WN *wn;
01474
01475 wn = WN_Create(OPC_IO_ITEM,kid_count);
01476 WN_io_item(wn) = ioitem;
01477 WN_set_ty(wn, ty);
01478
01479 return(wn);
01480 }
01481
01482 WN *WN_CreateEval(WN *exp)
01483 {
01484 WN *wn;
01485
01486 Is_True(OPCODE_is_expression(WN_opcode(exp)),
01487 ("Bad exp in WN_CreateEval"));
01488 wn = WN_Create(OPC_EVAL,1);
01489 WN_kid0(wn) = exp;
01490
01491 return(wn);
01492 }
01493
01494 WN *
01495 WN_CreatePragma (WN_PRAGMA_ID pragma_name, ST_IDX st, INT32 arg1, INT32 arg2)
01496 {
01497 WN *wn;
01498
01499 wn = WN_Create(OPC_PRAGMA,0);
01500 WN_pragma(wn) = pragma_name;
01501 WN_st_idx(wn) = st;
01502 WN_pragma_flags(wn) = 0;
01503 WN_pragma_arg1(wn) = arg1;
01504 WN_pragma_arg2(wn) = arg2;
01505
01506 return(wn);
01507 }
01508
01509 WN *
01510 WN_CreatePragma (WN_PRAGMA_ID pragma_name,
01511 ST_IDX st,
01512 INT32 arg1,
01513 PREG_NUM asm_copyout_preg,
01514 UINT32 asm_opnd_num)
01515 {
01516 WN *wn;
01517
01518 Is_True(pragma_name == WN_PRAGMA_ASM_CONSTRAINT,
01519 ("ASM_CONSTRAINT-specific CreatePragma can't be used for "
01520 "other pragmas"));
01521 wn = WN_Create(OPC_PRAGMA,0);
01522 WN_pragma(wn) = pragma_name;
01523 WN_st_idx(wn) = st;
01524 WN_pragma_flags(wn) = 0;
01525 WN_pragma_arg1(wn) = arg1;
01526 WN_set_pragma_asm_copyout_preg(wn, asm_copyout_preg);
01527 WN_set_pragma_asm_opnd_num(wn, asm_opnd_num);
01528
01529 return(wn);
01530 }
01531
01532 WN *WN_CreateXpragma(WN_PRAGMA_ID pragma_name, ST_IDX st, INT16 kid_count)
01533 {
01534 WN *wn;
01535
01536 wn = WN_Create(OPC_XPRAGMA, kid_count);
01537 WN_pragma(wn) = pragma_name;
01538 WN_st_idx(wn) = st;
01539 WN_pragma_flags(wn) = 0;
01540 WN_pragma_arg64(wn) = 0;
01541
01542 return(wn);
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552 WN *WN_CreateExp0(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc)
01553 {
01554 WN *wn;
01555
01556 wn = WN_Create(opr, rtype, desc, 0);
01557
01558 return(wn);
01559 }
01560
01561 WN *WN_CreateExp1(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,WN *kid0)
01562 {
01563 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01564 WN *wn;
01565
01566 Is_True(OPCODE_is_expression(WN_opcode(kid0)),
01567 ("Bad kid0 in WN_CreateExp1"));
01568
01569 wn = WN_SimplifyExp1(opc, kid0);
01570 if (!wn) {
01571 wn = WN_Create(opr, rtype, desc, 1);
01572 WN_kid0(wn) = kid0;
01573 }
01574 else {
01575
01576 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01577 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01578 }
01579 }
01580
01581 return(wn);
01582 }
01583
01584 WN *WN_CreateExp2(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, WN *kid0, WN *kid1)
01585 {
01586 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01587 WN *wn = NULL;
01588
01589 Is_True(OPCODE_is_expression(WN_opcode(kid0)),
01590 ("Bad kid0 in WN_CreateExp2"));
01591 Is_True(OPCODE_is_expression(WN_opcode(kid1)),
01592 ("Bad kid1 in WN_CreateExp2"));
01593
01594 #if 0 // with 32-bit MPY, need U8U4CVT to zero-out high-order 32 bits (bug 4637)
01595 Is_True(opr != OPR_MPY ||
01596 WN_operator(kid0) == OPR_INTCONST ||
01597 WN_operator(kid1) == OPR_INTCONST ||
01598 MTYPE_byte_size(WN_rtype(kid0)) == MTYPE_byte_size(WN_rtype(kid1)),
01599 ("inconsistent sizes in operands of MPY"));
01600 #endif
01601
01602
01603 #ifdef KEY
01604 if( !WN_has_side_effects(kid0) &&
01605 !WN_has_side_effects(kid1) &&
01606 !Disable_Simplification_For_FE)
01607 #endif
01608 wn = WN_SimplifyExp2(opc, kid0, kid1);
01609
01610 if (!wn) {
01611 wn = WN_Create(opr,rtype,desc,2);
01612 WN_kid0(wn) = kid0;
01613 WN_kid1(wn) = kid1;
01614 }
01615 else {
01616
01617 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01618 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01619 }
01620 }
01621
01622 return(wn);
01623 }
01624
01625 WN *WN_CreateExp3(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01626 WN *kid0, WN *kid1, WN *kid2)
01627 {
01628 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01629 WN *wn = NULL;
01630
01631 Is_True(OPCODE_is_expression(WN_opcode(kid0)),
01632 ("Bad kid0 in WN_CreateExp3"));
01633 Is_True(OPCODE_is_expression(WN_opcode(kid1)),
01634 ("Bad kid1 in WN_CreateExp3"));
01635 Is_True(OPCODE_is_expression(WN_opcode(kid2)),
01636 ("Bad kid2 in WN_CreateExp3"));
01637
01638
01639 #ifdef KEY
01640 if( !WN_has_side_effects(kid0) )
01641 #endif
01642 wn = WN_SimplifyExp3(opc, kid0, kid1, kid2);
01643
01644 if (!wn) {
01645 wn = WN_Create(opr,rtype,desc,3);
01646 WN_kid0(wn) = kid0;
01647 WN_kid1(wn) = kid1;
01648 WN_kid(wn,2) = kid2;
01649 }
01650 else {
01651
01652 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01653 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01654 }
01655 }
01656
01657 return(wn);
01658 }
01659
01660 WN *WN_CreateCvtl(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01661 INT16 cvtl_bits, WN* kid0)
01662 {
01663 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01664 WN *wn;
01665
01666 Is_True(OPCODE_operator(opc) == OPR_CVTL, ("Bad opcode in WN_CreateCvtl"));
01667
01668 wn = WN_SimplifyCvtl(opc, cvtl_bits, kid0);
01669 if (!wn) {
01670 wn = WN_CreateExp1(opr, rtype, desc, kid0);
01671 WN_cvtl_bits(wn) = cvtl_bits;
01672 }
01673 else {
01674
01675 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01676 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01677 }
01678 }
01679
01680 return(wn);
01681 }
01682
01683 WN *
01684 WN_CreateIload (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01685 WN_OFFSET offset, TY_IDX ty,
01686 TY_IDX load_addr_ty, WN *addr, UINT field_id)
01687 {
01688 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01689 WN *wn;
01690
01691 Is_True(MTYPE_is_pointer(WN_rtype(addr)) ||
01692 WN_rtype(addr) == MTYPE_U8 ||
01693 WN_rtype(addr) == MTYPE_U4 ||
01694 WN_rtype(addr) == MTYPE_I8 ||
01695 WN_rtype(addr) == MTYPE_I4,
01696 ("Bad addr in WN_CreateIload"));
01697
01698 Is_True(opr == OPR_ILOAD || opr == OPR_ILDBITS,
01699 ("Bad opcode in WN_CreateIload"));
01700
01701 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
01702
01703 addr = fe_combine_address_offset ( &offset, addr );
01704
01705 #endif
01706
01707 wn = WN_SimplifyIload(opc,offset,ty,field_id,load_addr_ty,addr);
01708 if (!wn) {
01709 #ifdef TARG_NVISA
01710 if ((MTYPE_byte_size(rtype) == 8 && MTYPE_byte_size(desc) == 4)
01711 || (MTYPE_byte_size(rtype) == 4 && MTYPE_byte_size(desc) == 8))
01712 {
01713
01714
01715
01716
01717
01718
01719 DevWarn("insert cvt of iload, %d %d", rtype, desc);
01720 wn = WN_CreateExp1(opr,desc,desc,addr);
01721 WN_load_offset(wn) = offset;
01722 WN_set_ty(wn,ty);
01723 WN_set_load_addr_ty(wn,load_addr_ty);
01724 WN_set_field_id(wn, field_id);
01725 wn = WN_Cvt(desc, rtype, wn);
01726 return wn;
01727 }
01728 #endif
01729 wn = WN_CreateExp1(opr,rtype,desc,addr);
01730 WN_load_offset(wn) = offset;
01731 WN_set_ty(wn,ty);
01732 WN_set_load_addr_ty(wn,load_addr_ty);
01733 WN_set_field_id(wn, field_id);
01734 }
01735 else {
01736
01737 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
01738 WN_MAP_Set(WN_SimpParentMap, wn, NULL);
01739 }
01740 }
01741
01742 return(wn);
01743 }
01744
01745 WN *
01746 WN_CreateIloadx (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01747 TY_IDX ty, TY_IDX load_addr_ty, WN *addr1,
01748 WN *addr2)
01749 {
01750 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01751 WN *wn;
01752
01753 Is_True(OPCODE_operator(opc) == OPR_ILOADX,
01754 ("Bad opcode in WN_CreateIloadx"));
01755 Is_True(WN_operator(addr1) == OPR_LDID,
01756 ("Bad address1 in WN_CreateIloadx"));
01757 Is_True(WN_operator(addr2) == OPR_LDID,
01758 ("Bad address2 in WN_CreateIloadx"));
01759 wn = WN_CreateExp2(opr,rtype,desc,addr1,addr2);
01760 WN_load_offset(wn) = 0;
01761 WN_set_ty(wn,ty);
01762 WN_set_load_addr_ty(wn,load_addr_ty);
01763 return(wn);
01764 }
01765
01766
01767 WN *WN_CreateMload (WN_OFFSET offset, TY_IDX ty,WN *addr, WN *num_bytes)
01768 {
01769 WN *wn;
01770
01771 Is_True(MTYPE_is_pointer(WN_rtype(addr)) ||
01772 WN_rtype(addr)==MTYPE_U8 ||
01773 WN_rtype(addr)==MTYPE_U4 ||
01774 WN_rtype(addr)==MTYPE_I8 ||
01775 WN_rtype(addr)==MTYPE_I4,
01776 ("Bad addr in WN_CreateMload"));
01777
01778 #if (defined(FRONT_END_C) || defined(FRONT_END_CPLUSPLUS)) && !defined(FRONT_END_MFEF77)
01779
01780 addr = fe_combine_address_offset ( &offset, addr );
01781
01782 #endif
01783
01784 wn = WN_CreateExp2(OPC_MLOAD,addr,num_bytes);
01785 WN_load_offset(wn) = offset;
01786 WN_set_ty(wn,ty);
01787
01788 return(wn);
01789 }
01790
01791
01792 WN *
01793 WN_CreateLdid (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01794 WN_OFFSET offset, ST_IDX st, TY_IDX ty, UINT field_id)
01795 {
01796 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01797 WN *wn;
01798
01799 Is_True (opr == OPR_LDID || opr == OPR_LDBITS,
01800 ("Bad opcode in WN_CreateLdid"));
01801 #ifdef FRONT_END
01802 Is_True (!((offset == 0) && (&St_Table [st] == Int32_Preg ||
01803 &St_Table [st] == Int64_Preg ||
01804 &St_Table [st] == Float32_Preg ||
01805 &St_Table [st] == Float64_Preg)),
01806 ("Preg offset 0 in WN_CreateLdid"));
01807 #endif
01808 #ifdef TARG_NVISA
01809 if ((MTYPE_byte_size(rtype) == 8 && MTYPE_byte_size(desc) == 4)
01810 || (MTYPE_byte_size(rtype) == 4 && MTYPE_byte_size(desc) == 8))
01811 {
01812
01813
01814
01815
01816
01817
01818 DevWarn("insert cvt of ldid, %d %d", rtype, desc);
01819 wn = WN_Create(opr,desc,desc,0);
01820 WN_load_offset(wn) = offset;
01821 WN_st_idx(wn) = st;
01822 WN_set_ty(wn,ty);
01823 WN_set_field_id(wn, field_id);
01824 wn = WN_Cvt(desc, rtype, wn);
01825 return wn;
01826 }
01827 #endif
01828 wn = WN_Create(opr,rtype,desc,0);
01829 WN_load_offset(wn) = offset;
01830 WN_st_idx(wn) = st;
01831 WN_set_ty(wn,ty);
01832 WN_set_field_id(wn, field_id);
01833
01834 return(wn);
01835 }
01836
01837
01838 WN *WN_CreateLda (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01839 WN_OFFSET offset, TY_IDX ty, ST_IDX st, UINT field_id)
01840 {
01841 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01842 WN *wn;
01843
01844 Is_True(MTYPE_is_pointer(OPCODE_rtype(opc)),
01845 ("Bad addr in WN_CreateLda"));
01846 Is_True(OPCODE_operator(opc) == OPR_LDA,
01847 ("Bad opcode in WN_CreateLda"));
01848 wn = WN_Create(opr,rtype,desc,0);
01849 WN_load_offset(wn) = offset;
01850 WN_st_idx(wn) = st;
01851 WN_set_ty(wn,ty);
01852 WN_set_field_id(wn, field_id);
01853
01854 return(wn);
01855 }
01856
01857 WN *
01858 WN_CreateIlda (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01859 WN_OFFSET offset, TY_IDX ty)
01860 {
01861 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01862 WN *wn;
01863
01864 Is_True(MTYPE_is_pointer(OPCODE_rtype(opc)),
01865 ("Bad addr in WN_CreateIlda"));
01866 Is_True(OPCODE_operator(opc) == OPR_ILDA,
01867 ("Bad opcode in WN_CreateIlda"));
01868 wn = WN_Create(opr,rtype,desc,0);
01869 WN_load_offset(wn) = offset;
01870 WN_set_ty(wn,ty);
01871
01872 return(wn);
01873 }
01874
01875
01876 WN *WN_CreateIdname(WN_OFFSET offset, ST_IDX st)
01877 {
01878 WN *wn;
01879
01880 wn = WN_Create(OPC_IDNAME, 0);
01881 WN_idname_offset(wn) = offset;
01882 WN_st_idx(wn) = st;
01883
01884 return(wn);
01885 }
01886
01887
01888 WN *WN_CreateConst(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, ST_IDX st)
01889 {
01890 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01891 WN *wn;
01892
01893 Is_True(OPCODE_operator(opc) == OPR_CONST,
01894 ("Bad opcode in WN_CreateConst"));
01895 wn = WN_Create(opr,rtype,desc,0);
01896 WN_st_idx(wn) = st;
01897
01898 return(wn);
01899 }
01900
01901 WN *WN_CreateIntconst(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, INT64 const_val)
01902 {
01903 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01904 WN *wn;
01905
01906 Is_True(OPCODE_operator(opc) == OPR_INTCONST,
01907 ("Bad opcode in WN_CreateIntconst"));
01908 wn = WN_Create(opr,rtype,desc,0);
01909 if (opc == OPC_U4INTCONST) {
01910 #ifndef TARG_X8664
01911
01912 UINT32 uval = const_val;
01913 INT32 sval = uval;
01914 WN_const_val(wn) = (INT64) sval;
01915 #else
01916
01917 WN_const_val(wn) = const_val & 0x0ffffffffLL;
01918 #endif
01919 } else {
01920 WN_const_val(wn) = const_val;
01921 }
01922
01923 return(wn);
01924 }
01925
01926 WN *WN_CreateComma(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01927 WN *block, WN *value)
01928 {
01929 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01930 WN *wn;
01931
01932 Is_True(OPCODE_is_expression(WN_opcode(value)),
01933 ("Bad value in WN_CreateComma"));
01934 Is_True(WN_opcode(block) == OPC_BLOCK,
01935 ("Bad block in WN_CreateComma"));
01936 wn = WN_Create(opr,rtype,desc,2);
01937 WN_kid0(wn) = block;
01938 WN_kid1(wn) = value;
01939
01940 #ifdef FRONT_END
01941 Set_PU_has_very_high_whirl (Get_Current_PU ());
01942 #endif
01943
01944 return(wn);
01945 }
01946
01947 WN *WN_CreateRcomma(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
01948 WN *value, WN *block)
01949 {
01950 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
01951 WN *wn;
01952
01953 Is_True(OPCODE_is_expression(WN_opcode(value)),
01954 ("Bad value in WN_CreateComma"));
01955 Is_True(WN_opcode(block) == OPC_BLOCK,
01956 ("Bad block in WN_CreateComma"));
01957 wn = WN_Create(opr,rtype,desc,2);
01958 WN_kid0(wn) = value;
01959 WN_kid1(wn) = block;
01960
01961 #ifdef FRONT_END
01962 Set_PU_has_very_high_whirl (Get_Current_PU ());
01963 #endif
01964
01965 return(wn);
01966 }
01967
01968 WN *WN_CreateAsm_Stmt (INT16 kid_count, char *asm_string)
01969 {
01970 WN *wn = WN_Create(OPC_ASM_STMT, kid_count);
01971
01972 ST *asm_st = New_ST(CURRENT_SYMTAB);
01973 WN_st_idx(wn) = ST_st_idx(asm_st);
01974 ST_Init(asm_st,
01975 Str_To_Index (Save_Str(asm_string), Current_Strtab),
01976 CLASS_NAME,
01977 SCLASS_UNKNOWN,
01978 EXPORT_LOCAL,
01979 (TY_IDX) 0);
01980
01981 return wn;
01982 }
01983
01984 WN *WN_CreateAsm_Input (char *constraint_string,
01985 UINT32 opnd_num,
01986 WN *value)
01987 {
01988 WN *wn = WN_Create(OPC_ASM_INPUT, 1);
01989
01990 ST *constraint_st = New_ST(CURRENT_SYMTAB);
01991 WN_st_idx(wn) = ST_st_idx(constraint_st);
01992 ST_Init(constraint_st,
01993 Str_To_Index (Save_Str(constraint_string), Current_Strtab),
01994 CLASS_NAME,
01995 SCLASS_UNKNOWN,
01996 EXPORT_LOCAL,
01997 (TY_IDX) 0);
01998
01999 WN_kid0(wn) = value;
02000 WN_asm_opnd_num(wn) = opnd_num;
02001 return wn;
02002 }
02003
02004 WN *WN_CreateComment (const char *s)
02005 {
02006 WN *wn;
02007 wn = WN_Create(OPC_COMMENT,0);
02008
02009 ST *comment_st = New_ST(CURRENT_SYMTAB);
02010 WN_st_idx(wn) = ST_st_idx(comment_st);
02011 ST_Init(comment_st,
02012 Str_To_Index (Save_Str(s), Current_Strtab),
02013 CLASS_NAME,
02014 SCLASS_UNKNOWN,
02015 EXPORT_LOCAL,
02016 (TY_IDX) 0);
02017
02018 return wn;
02019 }
02020
02021 STR_IDX WN_GetComment (const WN *wn)
02022 {
02023 Is_True(WN_opcode(wn) == OPC_COMMENT, ("Bad opcode in WN_GetComment"));
02024 return ST_name_idx(WN_st(wn));
02025 }
02026
02027 WN *WN_CopyNode (const WN* src_wn)
02028 {
02029 WN* wn;
02030 OPCODE opcode = WN_opcode(src_wn);
02031
02032 if (src_wn == NULL) return NULL;
02033 wn = WN_Create (opcode, WN_kid_count(src_wn));
02034
02035 WN_Copy_u1u2 (wn, src_wn);
02036 WN_Copy_u3 (wn, src_wn);
02037 #if defined(TARG_SL)
02038
02039 if(WN_is_internal_mem_ofst(src_wn))
02040 WN_Set_is_internal_mem_ofst(wn);
02041
02042 if(WN_is_compgoto_para(src_wn))
02043 WN_Set_is_compgoto_para(wn);
02044 else if(WN_is_compgoto_for_minor(src_wn))
02045 WN_Set_is_compgoto_for_minor(wn);
02046 #endif
02047
02048 WN_set_field_id(wn, WN_field_id(src_wn));
02049
02050 if (opcode == OPC_REGION && WN_ereg_supp(src_wn) != (INITO_IDX) 0) {
02051 const INITO& src_ino = Inito_Table[WN_ereg_supp (src_wn)];
02052 const ST *st = Copy_ST (INITO_st (src_ino));
02053 WN_ereg_supp(wn) = New_INITO (st, src_ino.val);
02054 }
02055
02056 if (OPCODE_has_next_prev(opcode)) {
02057 WN_linenum(wn) = WN_linenum(src_wn);
02058 }
02059 #ifdef KEY // bug 10105
02060 if (WN_kid_count(src_wn) == 3)
02061 WN_kid(wn, 2) = WN_kid(src_wn, 2);
02062 #endif
02063 return(wn);
02064 }
02065
02066 #if 0
02067
02068 void IPA_WN_Move_Maps (WN_MAP_TAB *maptab, WN *dst, WN *src)
02069 {
02070 INT32 i;
02071
02072
02073 if (OPCODE_mapcat(WN_opcode(dst)) == OPCODE_mapcat(WN_opcode(src))) {
02074 if (WN_map_id(dst) != WN_MAP_UNDEFINED) WN_MAP_Add_Free_List(maptab, dst);
02075 WN_map_id(dst) = WN_map_id(src);
02076 WN_map_id(src) = WN_MAP_UNDEFINED;
02077 return;
02078 }
02079
02080
02081 for (i = 0; i < WN_MAP_MAX; i++) {
02082 if (maptab->_is_used[i]) {
02083 switch (maptab->_kind[i]) {
02084 case WN_MAP_KIND_VOIDP: {
02085 IPA_WN_MAP_Set(maptab, i, dst, IPA_WN_MAP_Get(maptab, i, src));
02086 break;
02087 }
02088 case WN_MAP_KIND_INT32: {
02089 IPA_WN_MAP32_Set(maptab, i, dst, IPA_WN_MAP32_Get(maptab, i, src));
02090 break;
02091 }
02092 case WN_MAP_KIND_INT64: {
02093 IPA_WN_MAP64_Set(maptab, i, dst, IPA_WN_MAP64_Get(maptab, i, src));
02094 break;
02095 }
02096 default:
02097 Is_True(FALSE, ("WN_Move_Maps: unknown map kind"));
02098 }
02099 }
02100 }
02101
02102 WN_MAP_Add_Free_List(maptab, src);
02103 WN_map_id(src) = WN_MAP_UNDEFINED;
02104 }
02105 #endif
02106
02107 void IPA_WN_Move_Maps_PU (WN_MAP_TAB *src, WN_MAP_TAB *dst, WN *wn)
02108 {
02109 INT32 i;
02110 OPERATOR_MAPCAT category = OPCODE_mapcat(WN_opcode(wn));
02111 INT32 old_map_id = WN_map_id(wn);
02112 UINT c;
02113
02114 if (old_map_id == WN_MAP_UNDEFINED)
02115 return;
02116
02117 WN_MAP_Add_Free_List(src, wn);
02118 WN_set_map_id(wn, WN_MAP_UNDEFINED);
02119 WN_MAP_Set_ID(dst,wn);
02120
02121
02122
02123
02124
02125
02126 for (i = 0; i < WN_MAP_MAX; i++) {
02127 if (src->_is_used[i] && !WN_MAP_Get_dont_copy(i)) {
02128
02129 if (!dst->_is_used[i]) {
02130 dst->_is_used[i] = TRUE;
02131 for (c = 0; c < WN_MAP_CATEGORIES; c++) {
02132 dst->_map_size[c][i] = 0;
02133 dst->_mapping[c][i] = NULL;
02134 }
02135 dst->_pool[i] = src->_pool[i];
02136 dst->_kind[i] = src->_kind[i];
02137 }
02138
02139 switch (src->_kind[i]) {
02140 case WN_MAP_KIND_VOIDP: {
02141 if (old_map_id < src->_map_size[category][i]) {
02142 IPA_WN_MAP_Set(dst, i, wn, src->_mapping[category][i][old_map_id]);
02143 }
02144 break;
02145 }
02146 case WN_MAP_KIND_INT32: {
02147 if (old_map_id < src->_map_size[category][i]) {
02148 IPA_WN_MAP32_Set(dst, i, wn,
02149 ((INT32*) src->_mapping[category][i])[old_map_id]);
02150 }
02151 break;
02152 }
02153 case WN_MAP_KIND_INT64: {
02154 if (old_map_id < src->_map_size[category][i]) {
02155 IPA_WN_MAP64_Set(dst, i, wn,
02156 ((INT64*) src->_mapping[category][i])[old_map_id]);
02157 }
02158 break;
02159 }
02160 default:
02161 Is_True(FALSE, ("IPA_WN_Move_Maps_PU: unknown map kind"));
02162 }
02163 }
02164 }
02165
02166 }
02167
02168
02169 INT32
02170 WN_Size_and_StartAddress (WN *wn, void **StartAddress)
02171 {
02172 if (OPCODE_has_next_prev(WN_opcode(wn))) {
02173 *StartAddress = (void *)&(WN_prev(wn));
02174 return sizeof(WN) + sizeof(mUINT64) +
02175 (MAX (2, WN_kid_count(wn)) * sizeof(WN*));
02176 } else {
02177 *StartAddress = (void *) wn;
02178 return sizeof(WN) + MAX(0, WN_kid_count(wn) - 2) * sizeof(WN*);
02179 }
02180
02181 }
02182
02183
02184 WN *WN_CreateLoopInfo (WN *induction, WN *trip, UINT16 trip_est, UINT16 depth, INT32 flags)
02185 {
02186 WN *wn;
02187 INT16 nkids = 0;
02188 if (induction != NULL) nkids++;
02189 if (trip != NULL) nkids++;
02190 Is_True(!(induction==NULL && trip != NULL),
02191 ("trip must be null if induction is null in WN_CreateLoopInfo"));
02192
02193 wn = WN_Create (OPC_LOOP_INFO, nkids);
02194 WN_loop_trip_est(wn) = trip_est;
02195 WN_loop_depth(wn) = depth;
02196 WN_loop_flag(wn) = flags;
02197 if (induction) WN_set_loop_induction(wn, induction);
02198 if (trip) WN_set_loop_trip(wn, trip);
02199 return wn;
02200 }
02201
02202 WN *WN_CreateExcScopeBegin (INT32 id, INT16 nkids, INITO_IDX ereg_supp)
02203 {
02204 WN *wn;
02205 wn = WN_Create (OPC_EXC_SCOPE_BEGIN, nkids);
02206 WN_ereg_supp(wn) = ereg_supp;
02207 WN_offset(wn) = id;
02208 return wn;
02209 }
02210
02211 WN *WN_CreateExcScopeEnd (INT32 id)
02212 {
02213 WN *wn;
02214 wn = WN_Create (OPC_EXC_SCOPE_END, 0);
02215 WN_offset(wn) = id;
02216 return wn;
02217 }
02218
02219 WN *WN_CreateBarrier (BOOL forward, INT16 nkids)
02220 {
02221 WN *wn;
02222 if (forward)
02223 wn = WN_Create (OPC_FORWARD_BARRIER, nkids);
02224 else
02225 wn = WN_Create (OPC_BACKWARD_BARRIER, nkids);
02226 return wn;
02227 }
02228
02229 WN *WN_CreateTrap (INT32 value)
02230 {
02231 WN *wn;
02232 wn = WN_Create (OPC_TRAP, 0);
02233 WN_offset(wn) = value;
02234 return wn;
02235 }
02236
02237 WN *WN_CreateAssert (INT32 value, WN *condition)
02238 {
02239 WN *wn;
02240 wn = WN_Create (OPC_ASSERT, 1);
02241 WN_kid(wn,0) = condition;
02242 WN_offset(wn) = value;
02243 return wn;
02244 }
02245
02246 WN * WN_Zerocon (TYPE_ID ty)
02247 {
02248
02249 if (MTYPE_type_class(ty)&MTYPE_CLASS_INTEGER)
02250 return WN_Intconst(ty, (INT64) 0);
02251 else
02252 return Make_Const(Targ_Conv(ty, Host_To_Targ (MTYPE_I4, 0)));
02253 }
02254
02255 WN *WN_Tas(TYPE_ID rtype, TY_IDX ty, WN *l)
02256 {
02257 WN *tas;
02258
02259 tas = WN_CreateExp1(OPR_TAS, rtype, MTYPE_V, l);
02260
02261
02262 if (WN_operator_is(tas, OPR_TAS)) {
02263 WN_set_ty(tas, ty);
02264 }
02265
02266 return tas;
02267 }
02268
02269
02270
02271
02272
02273
02274
02275
02276 WN *WN_Create_Intrinsic(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
02277 INTRINSIC intrinsic, INT32 n, WN *kids[])
02278 {
02279 OPCODE opc = OPCODE_make_op (opr, rtype, desc);
02280 WN *call;
02281 INT32 i;
02282
02283 call = WN_SimplifyIntrinsic(opc, intrinsic, n, kids);
02284 if (!call) {
02285 call = WN_Create(opr, rtype, desc, n);
02286 WN_intrinsic(call) = intrinsic;
02287 for (i=0; i<n; i++) {
02288 WN_kid(call,i) = kids[i];
02289 }
02290 }
02291 else {
02292
02293 if (WN_SimpParentMap != WN_MAP_UNDEFINED) {
02294 WN_MAP_Set(WN_SimpParentMap, call, NULL);
02295 }
02296 }
02297
02298 return call;
02299 }
02300
02301 WN *WN_CreateParm(TYPE_ID rtype, WN *parm_node, TY_IDX ty, UINT32 flag)
02302 {
02303 OPCODE op = OPCODE_make_op(OPR_PARM, rtype, MTYPE_V);
02304 WN *wn;
02305
02306 if ( parm_node != NULL ) {
02307 if (op != OPC_VPARM) {
02308 Is_True( OPCODE_is_expression(WN_opcode(parm_node)),
02309 ("Bad parm_node in WN_CreateParm"));
02310 Is_True( Types_Are_Compatible (rtype, parm_node ),
02311 ("rtype and parm_node's rtype are different in WN_CreateParm"));
02312 }
02313 wn = WN_CreateExp1(op, parm_node);
02314 }
02315 else {
02316 Is_True( rtype == MTYPE_V,
02317 ("non-VOID type in WN_CreateParm with null parm_node") );
02318 wn = WN_CreateExp0(op);
02319 }
02320 WN_set_ty(wn, ty);
02321 WN_set_flag(wn, flag);
02322 return wn;
02323 }
02324
02325 WN *WN_Intconst(TYPE_ID rtype, INT64 value)
02326 {
02327 return WN_CreateIntconst(OPR_INTCONST, rtype, MTYPE_V, value);
02328 }
02329
02330 WN *WN_Ldid(TYPE_ID desc, WN_OFFSET offset, ST_IDX sym, TY_IDX align,
02331 UINT field_id)
02332 {
02333 TYPE_ID rtype= Mtype_comparison(desc);
02334
02335 return WN_CreateLdid (OPR_LDID, rtype, desc, offset, sym, align, field_id);
02336 }
02337
02338 WN *
02339 WN_RLdid (TYPE_ID rtype, TYPE_ID desc, WN_OFFSET offset, ST_IDX sym,
02340 TY_IDX align)
02341 {
02342 return WN_CreateLdid (OPR_LDID, rtype, desc, offset, sym, align);
02343 }
02344
02345 WN *WN_LdidPreg(TYPE_ID desc, WN_OFFSET pregno)
02346 {
02347 ST *preg = MTYPE_To_PREG(desc);
02348
02349 return WN_Ldid(desc, pregno, preg, ST_type(preg));
02350 }
02351
02352 WN *
02353 WN_Stid (TYPE_ID desc, WN_OFFSET offset, ST* sym, TY_IDX align, WN *value,
02354 UINT field_id)
02355 {
02356 return WN_CreateStid(OPR_STID, MTYPE_V, desc, offset, sym, align, value,
02357 field_id);
02358 }
02359
02360 WN *WN_StidIntoPreg(TYPE_ID desc, WN_OFFSET offset, ST* preg, WN *value)
02361 {
02362 return WN_CreateStid(OPR_STID, MTYPE_V, desc, offset, preg, ST_type(preg), value);
02363 }
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375 WN *WN_Iload(TYPE_ID desc, WN_OFFSET offset, TY_IDX align, WN *addr,
02376 UINT field_id)
02377 {
02378 TY_IDX palign;
02379 TYPE_ID rtype= Mtype_comparison(desc);
02380 palign = Make_Pointer_Type (align);
02381
02382 return WN_CreateIload (OPR_ILOAD, rtype, desc, offset, align, palign, addr,
02383 field_id);
02384 }
02385
02386 WN *
02387 WN_RIload (TYPE_ID rtype, TYPE_ID desc, WN_OFFSET offset, TY_IDX align,
02388 WN *addr, UINT field_id)
02389 {
02390 TY_IDX palign;
02391 palign = Make_Pointer_Type(align);
02392
02393 return WN_CreateIload (OPR_ILOAD, rtype, desc, offset, align, palign, addr,
02394 field_id);
02395 }
02396
02397 WN *
02398 WN_Istore (TYPE_ID desc, WN_OFFSET offset, TY_IDX align, WN *addr, WN *value,
02399 UINT field_id)
02400 {
02401 return WN_CreateIstore (OPR_ISTORE, MTYPE_V, desc, offset, align, value, addr,
02402 field_id);
02403 }
02404
02405 WN *WN_Unary(OPERATOR opr, TYPE_ID rtype, WN *l)
02406 {
02407 return WN_CreateExp1(opr, rtype, MTYPE_V, l);
02408 }
02409
02410 WN *WN_Binary(OPERATOR opr, TYPE_ID rtype, WN *l, WN *r)
02411 {
02412 return WN_CreateExp2(opr, rtype, MTYPE_V, l, r);
02413 }
02414
02415 WN *WN_Ternary(OPERATOR opr, TYPE_ID rtype, WN *kid0, WN *kid1, WN *kid2)
02416 {
02417 return WN_CreateExp3(opr, rtype, MTYPE_V, kid0, kid1, kid2);
02418 }
02419
02420 WN *
02421 WN_IloadLdid (TYPE_ID desc, WN_OFFSET offset, TY_IDX align, ST* sym,
02422 WN_OFFSET symOffset)
02423 {
02424 WN *ldid = WN_Ldid(Pointer_type, symOffset, sym, ST_type(sym));
02425
02426 return WN_Iload(desc, offset, align, ldid);
02427 }
02428
02429 WN *WN_Cvt(TYPE_ID desc, TYPE_ID rtype, WN *l)
02430 {
02431 return WN_CreateExp1(OPR_CVT, rtype, desc, l);
02432 }
02433
02434 WN *WN_Trunc(TYPE_ID desc, TYPE_ID rtype, WN *l)
02435 {
02436 return WN_CreateExp1(OPR_TRUNC, rtype, desc, l);
02437 }
02438
02439 WN *WN_Rnd(TYPE_ID desc, TYPE_ID rtype, WN *l)
02440 {
02441 return WN_CreateExp1(OPR_RND, rtype, desc, l);
02442 }
02443
02444 WN *WN_Ceil(TYPE_ID desc, TYPE_ID rtype, WN *l)
02445 {
02446 return WN_CreateExp1(OPR_CEIL, rtype, desc, l);
02447 }
02448
02449 WN *WN_Floor(TYPE_ID desc, TYPE_ID rtype, WN *l)
02450 {
02451 return WN_CreateExp1(OPR_FLOOR, rtype, desc, l);
02452 }
02453
02454 WN *WN_Relational(OPERATOR opr, TYPE_ID rtype, WN *l, WN *r)
02455 {
02456 return WN_CreateExp2(opr, Boolean_type, rtype, l, r);
02457 }
02458
02459 WN *WN_ConstPowerOf2( TYPE_ID type, INT32 n)
02460 {
02461
02462 switch(type)
02463 {
02464 case MTYPE_F4:
02465 case MTYPE_F8:
02466 case MTYPE_F10:
02467 case MTYPE_F16:
02468 case MTYPE_FQ:
02469 case MTYPE_C4:
02470 case MTYPE_C8:
02471 case MTYPE_C10:
02472 case MTYPE_CQ:
02473 {
02474 double val = pow( 2.0, n);
02475
02476 return Make_Const (Host_To_Targ_Float (type, val));
02477 }
02478 default:
02479 {
02480 INT64 one= 1;
02481 UINT64 val= one << n;
02482 Is_True(((0<=n) && (n <= 63)), ("invalid power of 2"));
02483 return WN_Intconst(type, val);
02484 }
02485 }
02486
02487 }
02488
02489 WN *WN_Floatconst( TYPE_ID type, double value)
02490 {
02491
02492 switch(type)
02493 {
02494 case MTYPE_F4:
02495 case MTYPE_F8:
02496 case MTYPE_F10:
02497 case MTYPE_FQ:
02498 case MTYPE_F16:
02499 case MTYPE_C4:
02500 case MTYPE_C8:
02501 case MTYPE_C10:
02502 case MTYPE_CQ:
02503 return Make_Const (Host_To_Targ_Float (type, value));
02504 #ifdef TARG_X8664
02505 case MTYPE_V16F4:
02506 return Make_Const (Create_Simd_Const (type,
02507 Host_To_Targ_Float (MTYPE_F4,
02508 value )));
02509 case MTYPE_V16F8:
02510 return Make_Const (Create_Simd_Const (type,
02511 Host_To_Targ_Float (MTYPE_F8,
02512 value )));
02513 #endif
02514 }
02515 Is_True(FALSE, ("expected floating const type"));
02516 return NULL;
02517 }
02518
02519 WN *WN_UVConst( TYPE_ID type)
02520 {
02521 switch(type)
02522 {
02523 case MTYPE_I1:
02524 case MTYPE_U1:
02525 return WN_Intconst( Mtype_TransferSign(type, MTYPE_I4), 0x5a);
02526 case MTYPE_I2:
02527 case MTYPE_U2:
02528 return WN_Intconst( Mtype_TransferSign(type, MTYPE_I4), 0x5a5a);
02529 case MTYPE_I4:
02530 case MTYPE_U4:
02531 #ifdef KEY
02532 return WN_Intconst(type, 0xffa5a5a5);
02533 #else
02534 return WN_Intconst(type, 0xfffa5a5a);
02535 #endif
02536 case MTYPE_I8:
02537 case MTYPE_U8:
02538 #ifdef KEY
02539 return WN_Intconst(type, 0xfff5a5a5fff5a5a5ll);
02540 #else
02541 return WN_Intconst(type, 0xfffa5a5afffa5a5all);
02542 #endif
02543 case MTYPE_F4:
02544 case MTYPE_F8:
02545 case MTYPE_F10:
02546 case MTYPE_FQ:
02547 case MTYPE_F16:
02548 case MTYPE_C4:
02549 case MTYPE_C8:
02550 case MTYPE_C10:
02551 case MTYPE_CQ:
02552 #ifdef TARG_X8664
02553 case MTYPE_V8I1:
02554 case MTYPE_V8I2:
02555 case MTYPE_M8I1:
02556 case MTYPE_M8I2:
02557 case MTYPE_V8I4:
02558 case MTYPE_M8I4:
02559 #endif
02560 return Make_Const (Host_To_Targ_UV(type));
02561 case MTYPE_STR:
02562 case MTYPE_M:
02563 case MTYPE_V:
02564 case MTYPE_B:
02565 break;
02566 }
02567
02568 Is_True(FALSE, ("expected Uninitialized Variable const type"));
02569 return NULL;
02570 }
02571
02572 #define NBITMASK(x) ((1ll<<(x))-1)
02573 WN *WN_RotateIntconst(WN *tree, INT32 rotate)
02574 {
02575 TYPE_ID type= WN_rtype(tree);
02576 INT32 size= MTYPE_size_reg(type);
02577 UINT64 n= WN_const_val(tree);
02578 UINT64 t;
02579
02580 Is_True(WN_operator_is(tree, OPR_INTCONST), ("expected INTCONST"));
02581
02582 rotate= rotate % size;
02583
02584 if (rotate>0)
02585 {
02586 UINT64 t= n & NBITMASK(rotate);
02587
02588 n >>= rotate;
02589 n &= NBITMASK(size-rotate);
02590 n = n | (t << (size - rotate));
02591 WN_const_val(tree)= n;
02592 }
02593 else if (rotate < 0)
02594 {
02595 rotate= -rotate;
02596
02597 t = n & ~NBITMASK(size - rotate);
02598 n <<= rotate;
02599 n &= NBITMASK(rotate);
02600 n = n | (t >> (size - rotate));
02601 WN_const_val(tree)= n;
02602 }
02603
02604 return tree;
02605 }
02606
02607 WN *WN_Inverse(TYPE_ID type, WN *tree)
02608 {
02609
02610
02611
02612
02613 if (MTYPE_float(type))
02614 {
02615 if (MTYPE_is_quad(type)==FALSE && Recip_Allowed == TRUE)
02616 {
02617 return WN_Recip(type, tree);
02618 }
02619 return WN_Div(type, WN_Floatconst(type, 1.0), tree);
02620 }
02621 return WN_Div(type, WN_Intconst(type, 1), tree);
02622 }
02623
02624 WN *
02625 WN_Lda (TYPE_ID rtype, WN_OFFSET ldaOffset, ST* sym, UINT field_id)
02626 {
02627 TY_IDX pty;
02628
02629
02630 TY_IDX ty;
02631
02632 if (ST_class (sym) == CLASS_BLOCK)
02633 ty = Make_Align_Type (MTYPE_To_TY(rtype), STB_align(sym));
02634 else
02635 ty = ST_class (sym) == CLASS_FUNC ? ST_pu_type (sym) : ST_type(sym);
02636 Is_True (ty != 0, ("WN_lda(): NULL ty"));
02637 pty = Make_Pointer_Type (ty);
02638
02639
02640 return WN_CreateLda(OPR_LDA, rtype, MTYPE_V, ldaOffset, pty, sym, field_id);
02641 }
02642
02643 WN *
02644 WN_LdaLabel (TYPE_ID rtype, INT32 label_number)
02645 {
02646 WN *wn;
02647 TY_IDX ty;
02648 ty = Make_Pointer_Type (Be_Type_Tbl (MTYPE_V));
02649 wn = WN_Create(OPR_LDA_LABEL, rtype, MTYPE_V, 0);
02650 WN_label_number (wn) = label_number;
02651 WN_set_ty (wn, ty);
02652 return wn;
02653 }
02654
02655 WN *WN_Icall(TYPE_ID rtype, TYPE_ID desc, INT32 n, TY_IDX ty)
02656 {
02657 WN *call;
02658
02659 call = WN_Create(OPR_ICALL, rtype, desc, n);
02660 WN_set_ty(call,ty);
02661
02662 return call;
02663 }
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675 WN *
02676 WN_generic_call (OPERATOR opr, TYPE_ID rtype, TYPE_ID desc, INT32 n,
02677 ST_IDX sym)
02678 {
02679 WN *call;
02680
02681 if (MTYPE_is_complex(rtype))
02682 rtype = Mtype_complex_to_real(rtype);
02683
02684 if (MTYPE_is_complex(desc))
02685 desc = Mtype_complex_to_real(desc);
02686
02687 call = WN_Create(opr, rtype, desc, n);
02688 WN_st_idx(call) = sym;
02689
02690 return call;
02691 }
02692
02693 void WN_CopyMap(WN *dst, WN_MAP map, const WN *src)
02694 {
02695 if ( map == WN_MAP_UNDEFINED )
02696 return;
02697
02698 switch ( Current_Map_Tab->_kind[map] ) {
02699 case WN_MAP_KIND_VOIDP:
02700 WN_MAP_Set( map, dst, WN_MAP_Get( map, src ) );
02701 break;
02702 case WN_MAP_KIND_INT32:
02703 WN_MAP32_Set( map, dst, WN_MAP32_Get( map, src ) );
02704 break;
02705 case WN_MAP_KIND_INT64:
02706 WN_MAP64_Set( map, dst, WN_MAP64_Get( map, src ) );
02707 break;
02708 default:
02709 Is_True( FALSE, ("WN_CopyMap: unknown map kind") );
02710 }
02711 }
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722 extern WN *
02723 WN_Int_Type_Conversion( WN *wn, TYPE_ID to_type )
02724 {
02725
02726 TYPE_ID from_type = WN_rtype(wn);
02727
02728 Is_True( from_type == MTYPE_I1 ||
02729 from_type == MTYPE_I2 ||
02730 from_type == MTYPE_I4 ||
02731 from_type == MTYPE_I8 ||
02732 from_type == MTYPE_U1 ||
02733 from_type == MTYPE_U2 ||
02734 from_type == MTYPE_U4 ||
02735 from_type == MTYPE_U8,
02736 ("WN_Int_Type_Conversion: bad from_type: %d\n", from_type) );
02737
02738
02739 if ( from_type == to_type )
02740 return wn;
02741
02742
02743
02744
02745 switch ( to_type ) {
02746 case MTYPE_I1:
02747 switch ( from_type ) {
02748 case MTYPE_I1:
02749 return wn;
02750 case MTYPE_I2:
02751 case MTYPE_I4:
02752 case MTYPE_U1:
02753 case MTYPE_U2:
02754 case MTYPE_U4:
02755 return WN_CreateCvtl( OPC_I4CVTL, 8, wn );
02756 case MTYPE_I8:
02757 case MTYPE_U8:
02758 return WN_CreateCvtl( OPC_I8CVTL, 8, wn );
02759 }
02760 case MTYPE_I2:
02761 switch ( from_type ) {
02762 case MTYPE_I1:
02763 case MTYPE_I2:
02764 return wn;
02765 case MTYPE_I4:
02766 case MTYPE_U1:
02767 case MTYPE_U2:
02768 case MTYPE_U4:
02769 return WN_CreateCvtl( OPC_I4CVTL, 16, wn );
02770 case MTYPE_I8:
02771 case MTYPE_U8:
02772 return WN_CreateCvtl( OPC_I8CVTL, 16, wn );
02773 }
02774 case MTYPE_I4:
02775 switch ( from_type ) {
02776 case MTYPE_I1:
02777 case MTYPE_I2:
02778 case MTYPE_I4:
02779 case MTYPE_U1:
02780 case MTYPE_U2:
02781 case MTYPE_U4:
02782 return wn;
02783 case MTYPE_I8:
02784 case MTYPE_U8:
02785 return WN_Cvt( from_type, to_type, wn );
02786 }
02787 case MTYPE_I8:
02788 switch ( from_type ) {
02789 case MTYPE_I1:
02790 case MTYPE_I2:
02791 case MTYPE_I4:
02792 case MTYPE_U1:
02793 case MTYPE_U2:
02794 case MTYPE_U4:
02795 return WN_Cvt( from_type, to_type, wn );
02796 case MTYPE_I8:
02797 case MTYPE_U8:
02798 return wn;
02799 }
02800 case MTYPE_U1:
02801 switch ( from_type ) {
02802 case MTYPE_I1:
02803 return wn;
02804 case MTYPE_I2:
02805 case MTYPE_I4:
02806 case MTYPE_U1:
02807 case MTYPE_U2:
02808 case MTYPE_U4:
02809 return WN_CreateCvtl( OPC_U4CVTL, 8, wn );
02810 case MTYPE_I8:
02811 case MTYPE_U8:
02812 return WN_CreateCvtl( OPC_U8CVTL, 8, wn );
02813 }
02814 case MTYPE_U2:
02815 switch ( from_type ) {
02816 case MTYPE_I1:
02817 case MTYPE_I2:
02818 case MTYPE_I4:
02819 case MTYPE_U4:
02820 return WN_CreateCvtl( OPC_U4CVTL, 16, wn );
02821 case MTYPE_U1:
02822 case MTYPE_U2:
02823 return wn;
02824 case MTYPE_I8:
02825 case MTYPE_U8:
02826 return WN_CreateCvtl( OPC_U8CVTL, 16, wn );
02827 }
02828 case MTYPE_U4:
02829 switch ( from_type ) {
02830 case MTYPE_I1:
02831 case MTYPE_I2:
02832 case MTYPE_I4:
02833 case MTYPE_U1:
02834 case MTYPE_U2:
02835 case MTYPE_U4:
02836 return wn;
02837 case MTYPE_I8:
02838 case MTYPE_U8:
02839 return WN_Cvt( from_type, to_type, wn );
02840 }
02841 case MTYPE_U8:
02842 switch ( from_type ) {
02843 case MTYPE_I1:
02844 case MTYPE_I2:
02845 case MTYPE_I4:
02846 case MTYPE_U1:
02847 case MTYPE_U2:
02848 case MTYPE_U4:
02849 return WN_Cvt( from_type, to_type, wn );
02850 case MTYPE_I8:
02851 case MTYPE_U8:
02852 return wn;
02853 }
02854 default:
02855 FmtAssert( FALSE,
02856 ("WN_Int_Type_Conversion: bad to_type: %d\n", to_type) );
02857 return wn;
02858 }
02859 }
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869 extern WN *
02870 WN_Float_Type_Conversion( WN *wn, TYPE_ID to_type )
02871 {
02872
02873 TYPE_ID from_type = WN_rtype(wn);
02874
02875 Is_True( from_type == MTYPE_F4 || from_type == MTYPE_F8 ||
02876 from_type == MTYPE_F10 || from_type == MTYPE_FQ,
02877 ("WN_Float_Type_Conversion: unexpected from_type: %d\n",from_type));
02878 Is_True( to_type == MTYPE_F4 || to_type == MTYPE_F8 ||
02879 to_type == MTYPE_F10 || to_type == MTYPE_FQ,
02880 ("WN_Float_Type_Conversion: unexpected to_type: %d\n", to_type) );
02881
02882
02883 if ( from_type == to_type )
02884 return wn;
02885 else
02886 return WN_Cvt( from_type, to_type, wn );
02887 }
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900 extern WN *
02901 WN_Type_Conversion( WN *wn, TYPE_ID to_type )
02902 {
02903
02904 TYPE_ID from_type = WN_rtype(wn);
02905 BOOL from_flt,to_flt;
02906
02907
02908
02909
02910 if(MTYPE_is_vector(from_type))
02911 return wn;
02912
02913
02914 if ( from_type == to_type )
02915 return wn;
02916
02917 Is_True( from_type == MTYPE_I1 ||
02918 from_type == MTYPE_I2 ||
02919 from_type == MTYPE_I4 ||
02920 from_type == MTYPE_I8 ||
02921 from_type == MTYPE_U1 ||
02922 from_type == MTYPE_U2 ||
02923 from_type == MTYPE_U4 ||
02924 from_type == MTYPE_U8 ||
02925 from_type == MTYPE_F4 ||
02926 from_type == MTYPE_F8 ||
02927 from_type == MTYPE_F10 ||
02928 from_type == MTYPE_FQ,
02929 ("WN_Type_Conversion: unexpected from_type: %d\n", from_type) );
02930 Is_True( to_type == MTYPE_I1 ||
02931 to_type == MTYPE_I2 ||
02932 to_type == MTYPE_I4 ||
02933 to_type == MTYPE_I8 ||
02934 to_type == MTYPE_U1 ||
02935 to_type == MTYPE_U2 ||
02936 to_type == MTYPE_U4 ||
02937 to_type == MTYPE_U8 ||
02938 to_type == MTYPE_F4 ||
02939 to_type == MTYPE_F8 ||
02940 to_type == MTYPE_F10 ||
02941 to_type == MTYPE_FQ,
02942 ("WN_Type_Conversion: unexpected to_type: %d\n", to_type) );
02943
02944 from_flt = MTYPE_is_float(from_type);
02945 to_flt = MTYPE_is_float(to_type);
02946
02947
02948 if ( from_flt ) {
02949 if ( to_flt ) {
02950
02951 return WN_Cvt( from_type, to_type, wn );
02952 }
02953
02954
02955 if ( MTYPE_size_min(to_type) >= 32 ) {
02956
02957 return WN_Cvt( from_type, to_type, wn );
02958 }
02959 else {
02960
02961 TYPE_ID tmp_to_type = Mtype_TransferSign( to_type, MTYPE_I4 );
02962 WN *tmp_wn = WN_Cvt( from_type, tmp_to_type, wn );
02963
02964
02965
02966
02967 return WN_Int_Type_Conversion( tmp_wn, to_type );
02968 }
02969 }
02970 else if ( to_flt ) {
02971
02972 if ( MTYPE_size_min(from_type) >= 32 ) {
02973
02974 return WN_Cvt( from_type, to_type, wn );
02975 }
02976 else {
02977
02978 TYPE_ID tmp_to_type = Mtype_TransferSign( to_type, MTYPE_I4 );
02979 WN *tmp_wn = WN_Int_Type_Conversion( wn, tmp_to_type );
02980
02981
02982 return WN_Cvt( tmp_to_type, to_type, tmp_wn );
02983 }
02984 }
02985 else {
02986
02987 return WN_Int_Type_Conversion( wn, to_type );
02988 }
02989 }
02990
02991
02992 WN *WN_Iloadx(TYPE_ID rtype, TY_IDX ty, TY_IDX addr_ty, WN *base, WN *index)
02993 {
02994 return WN_CreateIloadx(OPR_ILOADX, rtype, MTYPE_V, ty, addr_ty, base, index);
02995 }
02996
02997
02998 WN *WN_Istorex(TYPE_ID desc, TY_IDX ty, WN *value, WN *base, WN *index)
02999 {
03000 return WN_CreateIstorex(OPR_ISTOREX, MTYPE_V, desc, ty, value, base, index);
03001 }
03002
03003 WN *WN_LdaString(const char *str, WN_OFFSET ldaOffset, INT32 len)
03004 {
03005 TCON tc;
03006 ST *st;
03007
03008 tc = Host_To_Targ_String(MTYPE_STRING, str, len);
03009 st = Gen_String_Sym(&tc, MTYPE_To_TY(MTYPE_STRING), FALSE);
03010 return WN_Lda (Pointer_type, ldaOffset, st);
03011 }
03012
03013
03014 WN*
03015 WN_CreateAffirm (WN* condition)
03016 {
03017 WN* wn;
03018 wn = WN_Create (OPR_AFFIRM, MTYPE_V, MTYPE_V, 1);
03019 WN_kid0(wn) = condition;
03020 return wn;
03021 }
03022
03023 WN*
03024 WN_CreateAlloca (WN* size)
03025 {
03026 WN* wn;
03027 wn = WN_Create (OPR_ALLOCA, Pointer_Mtype, MTYPE_V, 1);
03028 WN_kid0(wn) = size;
03029 return wn;
03030 }
03031
03032 WN*
03033 WN_CreateDealloca (INT32 nkids)
03034 {
03035 WN* wn;
03036 wn = WN_Create (OPR_DEALLOCA, MTYPE_V, MTYPE_V, nkids);
03037 return wn;
03038 }
03039
03040 WN*
03041 WN_CreateLdma (TYPE_ID rtype, WN_OFFSET offset, TY_IDX ty, ST_IDX st)
03042 {
03043 WN *wn;
03044
03045 wn = WN_Create (OPR_LDMA, rtype, MTYPE_V, 0);
03046 WN_load_offset(wn) = offset;
03047 WN_st_idx(wn) = st;
03048 WN_set_ty(wn,ty);
03049
03050 return(wn);
03051 }
03052
03053
03054
03055
03056 void
03057 WN_set_st_addr_saved (WN* wn)
03058 {
03059 ST* st;
03060
03061 switch (WN_operator (wn)) {
03062
03063 case OPR_LDA:
03064 case OPR_LDMA:
03065
03066 st = WN_st(wn);
03067
03068 if ( ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_FUNC )
03069 Set_ST_addr_saved(st);
03070 break;
03071
03072 case OPR_ARRAY:
03073
03074 WN_set_st_addr_saved (WN_kid0(wn));
03075 break;
03076
03077 case OPR_LDID:
03078 case OPR_CONST:
03079 case OPR_ILOAD:
03080 case OPR_MLOAD:
03081 case OPR_INTCONST:
03082 case OPR_INTRINSIC_OP:
03083 case OPR_CALL:
03084 case OPR_EQ:
03085 case OPR_NE:
03086 case OPR_GT:
03087 case OPR_GE:
03088 case OPR_LT:
03089 case OPR_LE:
03090 case OPR_ALLOCA:
03091 #ifdef KEY
03092 case OPR_PURE_CALL_OP:
03093 #endif
03094
03095 break;
03096
03097 case OPR_EVAL:
03098 case OPR_TAS:
03099 case OPR_CVT:
03100 case OPR_CVTL:
03101 case OPR_NEG:
03102 case OPR_ABS:
03103 case OPR_SQRT:
03104 case OPR_REALPART:
03105 case OPR_IMAGPART:
03106 case OPR_PAREN:
03107 case OPR_RND:
03108 case OPR_TRUNC:
03109 case OPR_CEIL:
03110 case OPR_FLOOR:
03111 case OPR_BNOT:
03112 case OPR_LNOT:
03113 case OPR_LOWPART:
03114 case OPR_HIGHPART:
03115 case OPR_MINPART:
03116 case OPR_MAXPART:
03117 case OPR_RECIP:
03118 case OPR_RSQRT:
03119 case OPR_PARM:
03120 case OPR_OPTPARM:
03121 #ifdef TARG_X8664
03122 case OPR_ATOMIC_RSQRT:
03123 #endif
03124
03125 WN_set_st_addr_saved (WN_kid0(wn));
03126 break;
03127
03128 case OPR_CSELECT:
03129
03130 WN_set_st_addr_saved (WN_kid1(wn));
03131 WN_set_st_addr_saved (WN_kid2(wn));
03132 break;
03133
03134 case OPR_SELECT:
03135 case OPR_ADD:
03136 case OPR_SUB:
03137 case OPR_MPY:
03138 case OPR_DIV:
03139 case OPR_MOD:
03140 case OPR_REM:
03141 case OPR_DIVREM:
03142 case OPR_MAX:
03143 case OPR_MIN:
03144 case OPR_MINMAX:
03145 case OPR_BAND:
03146 case OPR_BIOR:
03147 case OPR_BXOR:
03148 case OPR_BNOR:
03149 case OPR_LAND:
03150 case OPR_LIOR:
03151 case OPR_SHL:
03152 case OPR_ASHR:
03153 case OPR_LSHR:
03154 case OPR_COMPLEX:
03155 case OPR_HIGHMPY:
03156
03157 WN_set_st_addr_saved (WN_kid0(wn));
03158 WN_set_st_addr_saved (WN_kid1(wn));
03159 break;
03160
03161 case OPR_CAND:
03162 case OPR_CIOR:
03163
03164 break;
03165
03166 case OPR_COMMA:
03167
03168 WN_set_st_addr_saved (WN_kid1(wn));
03169 break;
03170
03171 case OPR_RCOMMA:
03172
03173 WN_set_st_addr_saved (WN_kid0(wn));
03174 break;
03175
03176 #ifdef KEY
03177 case OPR_COMPOSE_BITS:
03178
03179 WN_set_st_addr_saved (WN_kid0(wn));
03180 WN_set_st_addr_saved (WN_kid1(wn));
03181 break;
03182
03183 case OPR_EXTRACT_BITS:
03184
03185 WN_set_st_addr_saved (WN_kid0(wn));
03186 break;
03187 #endif
03188
03189 #ifdef TARG_X8664
03190 case OPR_REPLICATE:
03191 case OPR_SHUFFLE:
03192
03193 WN_set_st_addr_saved (WN_kid0(wn));
03194 break;
03195 #endif // TARG_X8664
03196
03197 default:
03198
03199 Fail_FmtAssertion ("WN_set_st_addr_saved not implemented for %s",
03200 OPERATOR_name (WN_operator (wn)));
03201 break;
03202 }
03203 }
03204
03205
03206
03207 BOOL
03208 WN_has_side_effects (const WN* wn)
03209 {
03210 switch (WN_operator (wn)) {
03211
03212 case OPR_ABS:
03213 case OPR_BNOT:
03214 case OPR_CEIL:
03215 case OPR_CVT:
03216 case OPR_CVTL:
03217 case OPR_FIRSTPART:
03218 case OPR_FLOOR:
03219 case OPR_HIGHPART:
03220 case OPR_LOWPART:
03221 case OPR_LNOT:
03222 case OPR_MAXPART:
03223 case OPR_MINPART:
03224 case OPR_NEG:
03225 case OPR_PAREN:
03226 case OPR_PARM:
03227 case OPR_OPTPARM:
03228 case OPR_RND:
03229 case OPR_RSQRT:
03230 case OPR_RECIP:
03231 case OPR_SECONDPART:
03232 case OPR_SQRT:
03233 case OPR_TAS:
03234 case OPR_TRUNC:
03235 case OPR_EXTRACT_BITS:
03236 #ifdef TARG_X8664
03237 case OPR_REDUCE_ADD:
03238 case OPR_REDUCE_MAX:
03239 case OPR_REDUCE_MIN:
03240 case OPR_REDUCE_MPY:
03241 case OPR_SHUFFLE:
03242 case OPR_REPLICATE:
03243 case OPR_ATOMIC_RSQRT:
03244 #endif // TARG_X8664
03245 #ifdef KEY
03246 case OPR_ILDA:
03247 #endif // KEY
03248
03249 return WN_has_side_effects (WN_kid0(wn));
03250
03251 case OPR_ADD:
03252 case OPR_ASHR:
03253 case OPR_BAND:
03254 case OPR_BIOR:
03255 case OPR_BXOR:
03256 case OPR_BNOR:
03257 case OPR_DIV:
03258 case OPR_DIVREM:
03259 case OPR_EQ:
03260 case OPR_GT:
03261 case OPR_GE:
03262 case OPR_HIGHMPY:
03263 case OPR_LAND:
03264 case OPR_LE:
03265 case OPR_LIOR:
03266 case OPR_LSHR:
03267 case OPR_LT:
03268 case OPR_MAX:
03269 case OPR_MIN:
03270 case OPR_MINMAX:
03271 case OPR_MOD:
03272 case OPR_MPY:
03273 case OPR_NE:
03274 case OPR_PAIR:
03275 case OPR_REM:
03276 case OPR_SHL:
03277 case OPR_SUB:
03278 case OPR_XMPY:
03279 case OPR_COMPOSE_BITS:
03280 #ifdef KEY
03281 case OPR_RROTATE:
03282 #endif
03283
03284 if (WN_has_side_effects (WN_kid0(wn)))
03285 return TRUE;
03286
03287 return WN_has_side_effects (WN_kid1(wn));
03288
03289 case OPR_SELECT:
03290 case OPR_MADD:
03291 case OPR_MSUB:
03292 case OPR_NMADD:
03293 case OPR_NMSUB:
03294 #ifdef KEY
03295 case OPR_TRIPLET:
03296 #endif
03297
03298 if (WN_has_side_effects (WN_kid0(wn)))
03299 return TRUE;
03300
03301 if (WN_has_side_effects (WN_kid1(wn)))
03302 return TRUE;
03303
03304 return WN_has_side_effects (WN_kid2(wn));
03305
03306 case OPR_ARRAY:
03307
03308 if (WN_has_side_effects (WN_kid0(wn)))
03309 return TRUE;
03310
03311 else {
03312
03313 INT32 n = (WN_kid_count (wn)) >> 1;
03314
03315 for (INT32 i = n + 1; i <= 2 * n; i++) {
03316
03317 if (WN_has_side_effects (WN_kid (wn, i)))
03318 return TRUE;
03319 }
03320
03321 return FALSE;
03322 }
03323
03324 #ifdef KEY
03325 case OPR_PURE_CALL_OP:
03326 #endif
03327 case OPR_INTRINSIC_OP: {
03328
03329 INT32 n = WN_kid_count (wn);
03330
03331 for (INT32 i = 0; i < n; i++) {
03332
03333 if (WN_has_side_effects (WN_kid (wn, i)))
03334 return TRUE;
03335 }
03336
03337 return FALSE;
03338 }
03339
03340 case OPR_LDID:
03341 case OPR_LDBITS:
03342
03343 if (TY_is_volatile (WN_ty(wn)))
03344 return (TRUE);
03345
03346 return FALSE;
03347
03348 case OPR_ILOAD:
03349 case OPR_ILOADX:
03350 case OPR_ILDBITS:
03351
03352 if (TY_is_volatile (WN_ty(wn)) || TY_is_volatile(WN_load_addr_ty(wn)))
03353 return (TRUE);
03354
03355 return WN_has_side_effects (WN_kid0(wn));
03356
03357 case OPR_MLOAD:
03358
03359 if (TY_is_volatile (WN_ty(wn)))
03360 return (TRUE);
03361
03362 if (WN_has_side_effects (WN_kid0(wn)))
03363 return TRUE;
03364
03365 return WN_has_side_effects (WN_kid1(wn));
03366
03367 case OPR_CONST:
03368 case OPR_IDNAME:
03369 case OPR_INTCONST:
03370 case OPR_LDA:
03371 case OPR_LDMA:
03372 #ifdef KEY
03373 case OPR_LDA_LABEL:
03374 #endif
03375
03376 return FALSE;
03377
03378 case OPR_ALLOCA:
03379
03380 return TRUE;
03381
03382 case OPR_CAND:
03383 case OPR_CIOR:
03384
03385 return TRUE;
03386
03387 case OPR_COMMA:
03388 case OPR_RCOMMA:
03389
03390 return TRUE;
03391
03392 case OPR_CSELECT:
03393
03394 return TRUE;
03395
03396 #ifdef KEY
03397 case OPR_ASM_INPUT:
03398 return TRUE;
03399
03400 case OPR_ARRAYEXP:
03401 case OPR_ARRSECTION:
03402 return TRUE;
03403
03404 case OPR_WHERE:
03405 return TRUE;
03406
03407 case OPR_IO:
03408 case OPR_IO_ITEM:
03409 return TRUE;
03410
03411 case OPR_STID:
03412 case OPR_ISTBITS:
03413 case OPR_ISTORE:
03414 case OPR_ISTOREX:
03415 case OPR_STBITS:
03416 case OPR_MSTORE:
03417 return TRUE;
03418 #endif // KEY
03419
03420 default:
03421 Fail_FmtAssertion ("WN_has_side_effects not implemented for %s",
03422 OPERATOR_name (WN_operator (wn)));
03423
03424 return FALSE;
03425 }
03426 }
03427
03428
03429 WN *
03430 WN_Rrotate (TYPE_ID desc, WN *src, WN *cnt)
03431 {
03432 Set_PU_has_very_high_whirl (Get_Current_PU ());
03433 return WN_CreateExp2 (OPR_RROTATE, Mtype_comparison (desc), desc, src, cnt);
03434 }
03435
03436 #if !defined(FRONT_END_C) && !defined(IR_TOOLS) && defined(TARG_SL)
03437 BOOL WN_Intrinsic_OP_Slave (WN *wn) {
03438 if (WN_operator(wn) == OPR_INTRINSIC_OP) {
03439 INTRINSIC ins = WN_intrinsic(wn);
03440 if (INTRN_is_slave(ins))
03441 return TRUE;
03442 }
03443 return FALSE;
03444 }
03445 #endif