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