00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #ifdef USE_PCH
00082 #include "opt_pch.h"
00083 #endif // USE_PCH
00084 #pragma hdrstop
00085
00086
00087 #define __STDC_LIMIT_MACROS
00088 #include <stdint.h>
00089 #include "limits.h"
00090
00091 #define USE_STANDARD_TYPES
00092 #include "defs.h"
00093
00094 #include "stab.h"
00095 #include "irbdata.h"
00096 #include "config_targ.h"
00097 #include "config_opt.h"
00098 #include "targ_sim.h"
00099 #include "tracing.h"
00100 #include "stblock.h"
00101 #include "config.h"
00102 #include "wn_util.h"
00103 #include "wn_simp.h"
00104 #include "mempool.h"
00105 #include "be_symtab.h"
00106 #include "wn_lower.h"
00107 #include "opt_config.h"
00108 #include "erglob.h"
00109 #include "opt_htable.h"
00110 #include "opt_util.h"
00111 #include "opt_base.h"
00112 #include "opt_sym.h"
00113 #include "opt_cfg.h"
00114 #include "opt_ssa.h"
00115 #include "opt_wn.h"
00116 #include "opt_mu_chi.h"
00117 #include "opt_main.h"
00118 #include "opt_fold.h"
00119 #include "opt_alias_class.h"
00120 #ifdef KEY
00121 #include "opt_alias_rule.h"
00122 #endif
00123 #include "opt_points_to.h"
00124 #include "opt_cvtl_rule.h"
00125
00126 #include <algorithm>
00127
00128
00129
00130
00131 extern "C" {
00132 #include "targ_const.h"
00133 #include "stdlib.h"
00134 char *Targ_Print( const char *fmt, TCON cvalue );
00135 }
00136
00137 #ifdef Is_True_On
00138
00139
00140 extern WN_MAP Prompf_Id_Map;
00141 #endif // Is_True_On
00142
00143 #ifdef KEY
00144 static BOOL in_parallel_region = FALSE;
00145 #endif
00146
00147
00148
00149
00150
00151
00152
00153
00154 OPT_STAB::OPT_STAB(MEM_POOL *pool) : aux_stab(pool),
00155 _ac_2_vsym_map(256, (IDTYPE)0, pool, FALSE),
00156 _pt_sum(pool)
00157 {
00158 mem_pool = pool;
00159
00160
00161
00162
00163 OPT_POOL_Initialize(&_ver_pool, "VER Pool", FALSE, MEM_DUMP_FLAG+8);
00164 OPT_POOL_Initialize(&_occ_pool, "OCC Pool", FALSE, MEM_DUMP_FLAG+9);
00165 OPT_POOL_Initialize(&_st_chain_pool, "ST chain mapping", FALSE, MEM_DUMP_FLAG+12);
00166
00167
00168
00169 OPT_POOL_Push(&_ver_pool, MEM_DUMP_FLAG+8);
00170 OPT_POOL_Push(&_occ_pool, MEM_DUMP_FLAG+9);
00171 OPT_POOL_Push(&_st_chain_pool, MEM_DUMP_FLAG+12);
00172
00173 _default_vsym=0;
00174 Set_WN_sym_map(WN_MAP_Create(mem_pool));
00175 Set_WN_box_refs(WN_MAP_Create(mem_pool));
00176 Set_WN_box_defs(WN_MAP_Create(mem_pool));
00177
00178
00179 _const_found = 0;
00180
00181
00182 _rgn_trace = Get_Trace(TP_REGION, TT_REGION_WOPT_DEBUG) ||
00183 Get_Trace(TP_REGION, TT_REGION_BOUND_DEBUG) ||
00184 Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG);
00185
00186
00187 Set_points_to_globals( CXX_NEW( POINTS_TO, mem_pool ) );
00188 Points_to_globals()->Init();
00189 Points_to_globals()->Set_global();
00190 Points_to_globals()->Set_expr_kind(EXPR_IS_ADDR);
00191 Points_to_globals()->Set_base_kind(BASE_IS_UNKNOWN);
00192 Points_to_globals()->Set_ofst_kind(OFST_IS_UNKNOWN);
00193
00194
00195 _has_exc_handler = FALSE;
00196 #ifdef KEY
00197 _has_nonlocal_goto_target = FALSE;
00198 #endif
00199
00200 _ac_2_vsym_map.Init ();
00201 _pt_sum.Set_opt_stab (this);
00202
00203 BOOL t = Get_Trace (TP_GLOBOPT, CR_DUMP_FLAG);
00204 _cr_sr_annot_mgr = CXX_NEW (MEMOP_ANNOT_CR_SR_MGR (mem_pool, t), mem_pool);
00205 _cr_sr_annot_mgr->Set_active_mgr ();
00206 }
00207
00208
00209 OPT_STAB::~OPT_STAB(void)
00210 {
00211 WN_MAP_Delete(WN_sym_map());
00212 WN_MAP_Delete(WN_box_refs());
00213 WN_MAP_Delete(WN_box_defs());
00214
00215 CXX_DELETE (_cr_sr_annot_mgr, _cr_sr_annot_mgr->Mem_pool());
00216
00217
00218
00219 Opt_tlog( "SYM", 0, "PU static const %d", Const_found());
00220
00221 OPT_POOL_Pop(&_occ_pool, MEM_DUMP_FLAG+9);
00222
00223 OPT_POOL_Pop(&_st_chain_pool, MEM_DUMP_FLAG+12);
00224
00225 OPT_POOL_Delete(&_occ_pool, MEM_DUMP_FLAG+9);
00226
00227 OPT_POOL_Delete(&_st_chain_pool, MEM_DUMP_FLAG+12);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 static void
00257 Collect_addr_passed(WN *wn)
00258 {
00259 OPERATOR opr = WN_operator(wn);
00260
00261
00262
00263
00264 if (OPERATOR_is_call(opr)
00265 #ifdef KEY
00266 || opr == OPR_PURE_CALL_OP
00267 #endif
00268 )
00269 {
00270 for (INT i = 0; i < WN_kid_count(wn); i++)
00271 Collect_addr_passed(WN_kid(wn,i));
00272 }
00273 else if (opr == OPR_PARM)
00274 {
00275 Collect_addr_passed(WN_kid0(wn));
00276 }
00277 else if (OPERATOR_is_expression(opr))
00278 {
00279
00280
00281
00282
00283 if (OPERATOR_is_load(opr))
00284 return;
00285
00286 if (opr == OPR_LDA) {
00287 Set_BE_ST_addr_passed(WN_st_idx(wn));
00288 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
00289 fprintf(TFile, "set addr used locally: ");
00290 Print_ST(TFile, WN_st(wn), TRUE);
00291 }
00292 }
00293 for (INT i = 0; i < WN_kid_count(wn); i++)
00294 Collect_addr_passed(WN_kid(wn,i));
00295 }
00296 }
00297
00298
00299 static void
00300 Init_addr_passed_for_io(BOOL *collect_for_stmt, BOOL *collect_for_item)
00301 {
00302 INT i;
00303
00304
00305
00306
00307
00308
00309 for (i = 0; i <= IOSTATEMENT_LAST; i++) collect_for_stmt[i] = TRUE;
00310 for (i = 0; i <= IOITEM_LAST; i++) collect_for_item[i] = TRUE;
00311 }
00312
00313
00314 static void
00315 Collect_addr_passed_for_io(WN *wn)
00316 {
00317
00318
00319
00320 static BOOL collect_for_stmt[IOSTATEMENT_LAST+1];
00321 static BOOL collect_for_item[IOITEM_LAST+1];
00322 static BOOL initialized = FALSE;
00323
00324 if (!initialized)
00325 {
00326 initialized = TRUE;
00327 Init_addr_passed_for_io(collect_for_stmt, collect_for_item);
00328 }
00329
00330 Is_True(WN_operator(wn) == OPR_IO,
00331 ("Unexpected opcode in Collect_addr_passed_for_io()"));
00332
00333 if (collect_for_stmt[WN_io_statement(wn)])
00334 {
00335 for (INT io_kidno = 0;
00336 io_kidno < WN_kid_count(wn);
00337 io_kidno++)
00338 {
00339 WN * const io_item = WN_kid(wn, io_kidno);
00340
00341 Is_True(WN_operator(io_item) == OPR_IO_ITEM,
00342 ("Unexpected kid of IO stmt in "
00343 "Collect_addr_passed_for_io()"));
00344
00345 if (collect_for_item[WN_io_item(io_item)])
00346 {
00347 for (INT item_kidno = 0;
00348 item_kidno < WN_kid_count(io_item);
00349 item_kidno++)
00350 {
00351
00352
00353 Collect_addr_passed(WN_kid(io_item, item_kidno));
00354 }
00355 }
00356 }
00357 }
00358 }
00359
00360
00361 static void Collect_addr_passed_for_PU(WN *wn)
00362 {
00363 if (wn == NULL)
00364 return;
00365
00366
00367
00368 if (WN_operator(wn) == OPR_PARM && (
00369 #if defined(TARG_SL)
00370 WN_Parm_Dereference(wn) ||
00371 #endif
00372 WN_Parm_By_Reference(wn) || WN_Parm_Passed_Not_Saved(wn)))
00373 Collect_addr_passed(WN_kid0(wn));
00374
00375
00376
00377 else if (WN_operator(wn) == OPR_IO)
00378 Collect_addr_passed_for_io(wn);
00379
00380 if (WN_operator(wn) == OPR_BLOCK)
00381 for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))
00382 Collect_addr_passed_for_PU(stmt);
00383 else if ( !OPERATOR_is_black_box( WN_operator(wn) ) ) {
00384 for (INT32 i = 0; i < WN_kid_count(wn); i++)
00385 Collect_addr_passed_for_PU(WN_kid(wn,i));
00386 }
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 static INT32 aux_sym_cnt;
00409
00410
00411 void
00412 OPT_STAB::Count_syms(WN *wn)
00413 {
00414 INT32 i;
00415 WN *stmt;
00416
00417 if (wn == NULL)
00418 return;
00419
00420 if (OPERATOR_has_aux(WN_operator(wn)) &&
00421 WN_st(wn) != NULL) {
00422 ST *st = WN_st(wn);
00423 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(WN_st_idx(wn));
00424 if (st_chain_info == NULL) {
00425
00426
00427 aux_sym_cnt++;
00428 st_chain_info = CXX_NEW(ST_CHAIN_INFO, &_st_chain_pool);
00429 st_chain_info->Set_list_head(aux_sym_cnt);
00430 st_chain_map->Insert(WN_st_idx(wn), st_chain_info);
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 BOOL done = FALSE;
00446 while (!done) {
00447 done = TRUE;
00448 BOOL const_initialized = ST_is_const_initialized(st);
00449 if (const_initialized || (ST_is_initialized(st) &&
00450 ST_sclass(st) == SCLASS_PSTATIC)) {
00451 INITV_IDX initv = ST_has_initv(st);
00452 if (initv &&
00453 INITV_kind(Initv_Table[initv]) == INITVKIND_SYMOFF) {
00454 st = &St_Table[INITV_st(Initv_Table[initv])];
00455 if (const_initialized || ST_class(st) == CLASS_VAR) {
00456 st_chain_info = st_chain_map->Lookup(ST_st_idx(st));
00457 if (st_chain_info == NULL) {
00458 aux_sym_cnt++;
00459 st_chain_info = CXX_NEW(ST_CHAIN_INFO, &_st_chain_pool);
00460 st_chain_info->Set_list_head(aux_sym_cnt);
00461 st_chain_map->Insert(ST_st_idx(st), st_chain_info);
00462 done = FALSE;
00463 }
00464 }
00465 }
00466 }
00467 }
00468 }
00469 }
00470
00471
00472 if (OPERATOR_is_scalar_load (WN_operator(wn)) ||
00473 OPERATOR_is_scalar_store (WN_operator(wn))) {
00474 ST *st = WN_st(wn);
00475 if (ST_class(st) == CLASS_VAR)
00476 Clear_BE_ST_addr_used_locally(st);
00477 }
00478
00479 if (WN_operator(wn) == OPR_REGION && REGION_is_EH(wn))
00480 _has_exc_handler = TRUE;
00481 #ifdef KEY
00482 if (PU_has_nonlocal_goto_label(Get_Current_PU()))
00483 _has_nonlocal_goto_target = TRUE;
00484 #endif
00485
00486
00487 if (WN_operator(wn) == OPR_REGION) {
00488 RID *rid = REGION_get_rid(wn);
00489 Is_True(rid != NULL,("OPT_STAB::Count_syms, NULL rid"));
00490 if (RID_level(rid) >= Rgn_level())
00491 return;
00492 }
00493
00494
00495
00496
00497 if (WN_operator(wn) == OPR_CALL && WOPT_Enable_Pt_Summary) {
00498 PU_POINTS_TO_SUMMARY* sum = _pt_sum.Get_bound_pt_sum (wn);
00499 if (sum) {
00500 UNAME_VECTOR& ptrs = sum->Out_set().Name_space()->All_names();
00501 for (UNAME_VECTOR_ITER iter = ptrs.begin ();
00502 iter != ptrs.end (); iter++) {
00503 UNIFORM_NAME* name = *iter;
00504 if (name->Type () == UN_NAMED_GLOBAL) {
00505 ST* st = name->ST_for_named_global ();
00506 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_index(st));
00507 if (st_chain_info == NULL) {
00508 aux_sym_cnt++;
00509 st_chain_info = CXX_NEW(ST_CHAIN_INFO, &_st_chain_pool);
00510 st_chain_info->Set_list_head(aux_sym_cnt);
00511 st_chain_map->Insert(ST_st_idx(st), st_chain_info);
00512 }
00513 }
00514 }
00515 }
00516 }
00517
00518
00519 if (WN_operator(wn) == OPR_FORWARD_BARRIER ||
00520 WN_operator(wn) == OPR_BACKWARD_BARRIER) {
00521
00522 for (INT i = 0; i < WN_kid_count(wn); i++) {
00523 if (WN_operator(WN_kid(wn,i)) == OPR_IDNAME) {
00524 DevWarn("old style BARRIER: converting IDNAME kid of BARRIER"
00525 " into IDNAME.");
00526 OPCODE op = OPCODE_make_op(OPR_LDA, Pointer_type, MTYPE_V);
00527 ST *st = WN_st(WN_kid(wn,i));
00528 WN *lda = WN_CreateLda(op, 0, ST_type(st), st);
00529 WN_kid(wn,i) = lda;
00530 }
00531 }
00532 }
00533
00534 if (WN_operator(wn) == OPR_BLOCK)
00535 for (stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))
00536 Count_syms(stmt);
00537 else if ( !OPERATOR_is_black_box( WN_operator(wn) ) ) {
00538 for (i = 0; i < WN_kid_count(wn); i++)
00539 Count_syms(WN_kid(wn,i));
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 const char *
00552 AUX_STAB_ENTRY::St_name(void)
00553 {
00554 if (st) {
00555 if (ST_class(st) == CLASS_CONST)
00556 return Targ_Print(NULL, STC_val(st));
00557 else
00558 return ST_name(st);
00559 } else {
00560 return "null";
00561 }
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 inline BOOL
00575 Check_volatility( WN *wn, ST *st )
00576 {
00577 Is_True(WN_ty(wn) != 0, ("WN has null TY."));
00578
00579
00580 if ( TY_is_volatile(WN_ty(wn)) )
00581 return TRUE;
00582
00583 if (ST_class(st) != CLASS_VAR)
00584 return FALSE;
00585
00586 if ( TY_is_volatile(ST_type(st)) ) {
00587
00588
00589 if ( ! TY_is_volatile(WN_ty(wn)) ) {
00590
00591
00592
00593
00594 TY_IDX vty = WN_ty(wn);
00595 Set_TY_is_volatile(vty);
00596 WN_set_ty(wn, vty);
00597 }
00598 return TRUE;
00599 }
00600
00601
00602 return FALSE;
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 static UINT64 Desc_type_byte_size(const WN* wn) {
00623 Is_True(WN_operator(wn) == OPR_LDID || WN_operator(wn) == OPR_STID,
00624 ("Desc_type_byte_size: operator not LDID or STID"));
00625 Is_True(WN_desc(wn) == MTYPE_M, ("Desc_type_byte_size: desc not MTYPE_M"));
00626 TY_IDX ty_idx = WN_ty(wn);
00627 UINT field_id = WN_field_id(wn);
00628 if (field_id != 0) {
00629 Is_True(TY_kind(ty_idx) == KIND_STRUCT,
00630 ("Desc_type_size_min: expecting KIND_STRUCT"));
00631 UINT cur_field_id = 0;
00632 FLD_HANDLE fld = FLD_get_to_field(ty_idx, field_id, cur_field_id);
00633 Is_True(! fld.Is_Null(),
00634 ("Desc_type_byte_size: Invalid field id %d for type 0x%x",
00635 field_id, ty_idx));
00636 ty_idx = FLD_type(fld);
00637 }
00638 return TY_size(ty_idx);
00639 }
00640
00641 #ifdef KEY
00642
00643
00644
00645 static UINT64 Field_type_byte_size(const WN* wn, BOOL& fld_correct)
00646 {
00647 fld_correct = TRUE;
00648 Is_True (WN_operator(wn) == OPR_LDA,
00649 ("Field_type_byte_size: operator not LDA"));
00650 TY_IDX ty_idx = WN_ty(wn);
00651 Is_True (TY_kind(ty_idx) == KIND_POINTER,
00652 ("Field_type_byte_size: expected pointer type"));
00653 UINT field_id = WN_field_id(wn);
00654 Is_True (field_id, ("Field_type_byte_size: Expected non-zero field-id"));
00655 TY_IDX pointee = TY_pointed(ty_idx);
00656 while (TY_kind(pointee) == KIND_ARRAY)
00657 pointee = TY_etype(pointee);
00658 Is_True (TY_kind(pointee) == KIND_STRUCT,
00659 ("Field_type_byte_size: Field-id can only be in a struct"));
00660 UINT cur_field_id = 0;
00661 FLD_HANDLE fld = FLD_get_to_field(pointee, field_id, cur_field_id);
00662
00663 if (fld.Is_Null() || (FLD_ofst(fld) != WN_offset(wn)))
00664 {
00665 fld_correct = FALSE;
00666 return 0;
00667 }
00668 TY_IDX fld_ty_idx = FLD_type(fld);
00669 return TY_size(fld_ty_idx);
00670 }
00671
00672
00673
00674 static INT32 Get_byte_size (ST * st, WN * wn, UINT& field_id)
00675 {
00676 INT32 byte_size = 0;
00677
00678 if (ST_class(st) == CLASS_VAR)
00679 {
00680 if (wn && WN_field_id(wn))
00681 {
00682 BOOL fld_correct;
00683 INT32 size = Field_type_byte_size (wn, fld_correct);
00684 if (fld_correct)
00685 {
00686 byte_size = size;
00687 field_id = WN_field_id(wn);
00688 }
00689 else byte_size = TY_size(ST_type(st));
00690 }
00691 else byte_size = TY_size(ST_type(st));
00692 }
00693 return byte_size;
00694 }
00695 #endif
00696
00697
00698
00699
00700 AUX_ID
00701 OPT_STAB::Enter_symbol(OPERATOR opr, ST* st, INT64 ofst,
00702 TY_IDX wn_object_ty, BOOL is_volatile, WN* wn)
00703 {
00704 Is_True(st, ("Enter_symbol: can't enter NULL symbol."));
00705
00706 INT32 stype, byte_size;
00707 UINT8 bit_ofst = 0;
00708 UINT8 bit_size = 0;
00709 INT32 mclass = 0;
00710 MTYPE mtype = MTYPE_UNKNOWN;
00711 BOOL is_virtual = FALSE;
00712 BOOL is_scalar = FALSE;
00713 BOOL no_register = FALSE;
00714 BOOL dmod = FALSE;
00715 UINT field_id = 0;
00716 #ifdef KEY
00717 BOOL is_bit_field = FALSE;
00718 #endif
00719 TY_IDX hl_ty = (TY_IDX)0;
00720
00721 switch (opr) {
00722 case OPR_LDA:
00723 is_virtual = TRUE;
00724 #ifdef KEY
00725 byte_size = Get_byte_size (st, wn, field_id);
00726 #else
00727 byte_size = (ST_class(st) == CLASS_VAR) ? TY_size(ST_type(st)) : 0;
00728 #endif
00729 stype = VT_LDA_SCALAR;
00730 break;
00731 case OPR_LDBITS:
00732 bit_size = WN_bit_size(wn);
00733 bit_ofst = WN_bit_offset(wn);
00734
00735 case OPR_LDID:
00736 if (WN_desc(wn) == MTYPE_BS) {
00737 UINT cur_field_id = 0;
00738 UINT64 field_offset = 0;
00739 FLD_HANDLE fld = FLD_And_Offset_From_Field_Id(WN_ty(wn), WN_field_id(wn),
00740 cur_field_id, field_offset);
00741 ofst += field_offset;
00742 bit_size = FLD_bsize(fld);
00743 bit_ofst = FLD_bofst(fld);
00744 wn_object_ty = FLD_type(fld);
00745 byte_size = TY_size(wn_object_ty);
00746 #ifdef KEY
00747 is_bit_field = TRUE;
00748 #else
00749 field_id = WN_field_id(wn);
00750 #endif
00751 }
00752 else if (WN_desc(wn) == MTYPE_M) {
00753 byte_size = Desc_type_byte_size(wn);
00754 if (opr != OPR_LDBITS) {
00755 no_register = TRUE;
00756 }
00757 } else {
00758 byte_size = MTYPE_size_min(WN_desc(wn)) >> 3;
00759 if (ST_sclass(st) == SCLASS_REG)
00760 byte_size = TY_size(ST_type(st));
00761 }
00762 mtype = WN_rtype(wn);
00763 mclass = Get_mtype_class(mtype);
00764 is_scalar = TRUE;
00765 stype = VT_NO_LDA_SCALAR;
00766 #ifdef KEY
00767 if (opr == OPR_LDID)
00768 field_id = WN_field_id(wn);
00769 #endif
00770 if (WN_field_id(wn) != (TY_IDX)0) {
00771 UINT32 dummy;
00772 WN_hl_object_ty(wn, hl_ty, dummy);
00773 }
00774 break;
00775 case OPR_STBITS:
00776 bit_size = WN_bit_size(wn);
00777 bit_ofst = WN_bit_offset(wn);
00778
00779 case OPR_STID:
00780 if (WN_desc(wn) == MTYPE_BS) {
00781 UINT cur_field_id = 0;
00782 UINT64 field_offset = 0;
00783 FLD_HANDLE fld = FLD_And_Offset_From_Field_Id(WN_ty(wn), WN_field_id(wn),
00784 cur_field_id, field_offset);
00785 ofst += field_offset;
00786 bit_size = FLD_bsize(fld);
00787 bit_ofst = FLD_bofst(fld);
00788 wn_object_ty = FLD_type(fld);
00789 byte_size = TY_size(wn_object_ty);
00790 #ifdef KEY
00791 is_bit_field = TRUE;
00792 #else
00793 field_id = WN_field_id(wn);
00794 #endif
00795 }
00796 else {
00797 if (WN_desc(wn) == MTYPE_M) {
00798 byte_size = Desc_type_byte_size(wn);
00799 if (opr != OPR_STBITS) {
00800 no_register = TRUE;
00801 }
00802 } else
00803 byte_size = MTYPE_size_min(WN_desc(wn)) >> 3;
00804 if (ST_sclass(st) == SCLASS_REG)
00805 byte_size = TY_size(ST_type(st));
00806 }
00807 mtype = WN_desc(wn);
00808 mclass = Get_mtype_class(mtype);
00809 dmod = TRUE;
00810 is_scalar = TRUE;
00811 stype = VT_NO_LDA_SCALAR;
00812 #ifdef KEY
00813 if (opr == OPR_STID)
00814 field_id = WN_field_id(wn);
00815 #endif
00816 if (WN_field_id(wn) != (TY_IDX)0) {
00817 UINT32 dummy;
00818 WN_hl_object_ty(wn, hl_ty, dummy);
00819 }
00820 break;
00821 default:
00822 stype = VT_OTHER;
00823 byte_size = 0;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_st_idx(st));
00834 Is_True(st_chain_info != NULL,
00835 ("OPT_STAB::Enter_symbol: st chain must be defined.\n"));
00836 AUX_ID idx = st_chain_info->List_head();
00837 Is_True(idx != 0, ("OPT_STAB::Enter_symbol: idx is 0."));
00838
00839
00840 while (idx && aux_stab[idx].St() != NULL) {
00841 #if 0 // necessitated by the fix to bug 6293
00842 Is_True(aux_stab[idx].St() == st,
00843 ("Enter_aux_stab::lookup wrong ST chain."));
00844 #endif
00845 BOOL kind_match = FALSE;
00846 switch (aux_stab[idx].Stype()) {
00847 case VT_NO_LDA_SCALAR:
00848 case VT_LDA_SCALAR:
00849 kind_match = ((is_scalar && aux_stab[idx].Mclass() == mclass)
00850 || is_virtual);
00851 break;
00852 case VT_LDA_VSYM:
00853 case VT_UNIQUE_VSYM:
00854 case VT_SPECIAL_VSYM:
00855 kind_match = is_scalar || is_virtual;
00856 break;
00857 case VT_OTHER:
00858
00859 kind_match = (stype == VT_OTHER);
00860 break;
00861 default:
00862 break;
00863 }
00864
00865 if (kind_match &&
00866 aux_stab[idx].Byte_size() == byte_size &&
00867 #ifdef KEY // bug 12321
00868 aux_stab[idx].St() == st &&
00869 #endif
00870 aux_stab[idx].St_ofst() == ofst &&
00871 aux_stab[idx].Bit_size() == bit_size &&
00872 aux_stab[idx].Bit_ofst() == bit_ofst &&
00873 #ifdef KEY
00874 (!is_bit_field || (aux_stab[idx].Field_id() == field_id))
00875 #else
00876 aux_stab[idx].Field_id() == field_id
00877 #endif
00878 ) {
00879
00880 if ( is_volatile && ! aux_stab[idx].Is_volatile() ) {
00881 aux_stab[idx].Set_volatile();
00882 }
00883 #ifdef KEY // bug 5401 and 5267
00884 else if (in_parallel_region && OPERATOR_is_scalar_store(opr) &&
00885 ST_sclass(st) != SCLASS_REG)
00886 aux_stab[idx].Set_mp_no_dse();
00887 #endif
00888
00889 if (is_scalar) {
00890 if (!aux_stab[idx].Is_real_var())
00891 aux_stab[idx].Set_stype(VT_LDA_SCALAR);
00892 aux_stab[idx].Set_mclass(mclass);
00893 aux_stab[idx].Set_mtype(mtype);
00894 }
00895 if (is_virtual && !aux_stab[idx].Is_virtual())
00896 aux_stab[idx].Set_stype(VT_LDA_SCALAR);
00897
00898 if (no_register) {
00899 aux_stab[idx].Set_no_register();
00900 }
00901
00902 if (dmod) aux_stab[idx].Set_dmod();
00903 return idx;
00904 }
00905 idx = aux_stab[idx].St_chain();
00906 }
00907
00908
00909
00910
00911
00912
00913
00914 Is_True(idx != 0 || aux_stab[idx].St() == NULL,
00915 ("OPT_STAB::Enter_symbol: Robert misunderstood the logic"));
00916 if (idx == 0 || aux_stab[idx].St() != NULL) {
00917
00918 idx = aux_stab.Newidx();
00919 aux_stab[idx].Set_st_chain(st_chain_info->List_head());
00920 } else {
00921
00922
00923 aux_stab[idx].Set_st_chain((AUX_ID) 0);
00924 }
00925
00926
00927 st_chain_info->Set_list_head(idx);
00928
00929 AUX_STAB_ENTRY *sym = Aux_stab_entry(idx);
00930
00931 sym->Set_stype(stype);
00932 sym->Clear_flags();
00933 sym->Set_st(st);
00934 sym->Set_st_ofst(ofst);
00935 sym->Set_nonzerophis(NULL);
00936 sym->Set_aux_id_list(NULL);
00937 sym->Set_st_group((AUX_ID) 0);
00938 sym->Set_synonym((AUX_ID) 0);
00939 sym->Set_home_sym((AUX_ID) 0);
00940 sym->Set_zero_cr(NULL);
00941 sym->Set_field_id(field_id);
00942 sym->Set_mclass(0);
00943 sym->Set_mtype(MTYPE_UNKNOWN);
00944 sym->Set_def_bbs(NULL);
00945
00946 #ifdef KEY
00947
00948 sym->Set_value_size(0);
00949 sym->Set_spre_node(NULL);
00950
00951 if (opr == OPR_LDID || opr == OPR_STID)
00952 sym->Set_wn(wn);
00953 #endif
00954
00955 if (is_scalar) {
00956 sym->Set_stype(VT_NO_LDA_SCALAR);
00957 sym->Set_mclass(mclass);
00958 sym->Set_mtype(mtype);
00959 }
00960 if (is_virtual) {
00961 sym->Set_stype(VT_LDA_VSYM);
00962 sym->Set_mclass(0);
00963 sym->Set_mtype(MTYPE_UNKNOWN);
00964 }
00965
00966 if (no_register) {
00967 sym->Set_no_register();
00968 }
00969
00970 if (dmod) sym->Set_dmod();
00971 if ( is_volatile ) sym->Set_volatile();
00972
00973 #ifdef KEY // bug 5401 and 5267
00974 if (in_parallel_region && OPERATOR_is_scalar_store(opr) &&
00975 ST_sclass(st) != SCLASS_REG)
00976 sym->Set_mp_no_dse();
00977 #endif
00978
00979 if (ST_class(st) == CLASS_VAR && ST_has_nested_ref(st)) {
00980 sym->Set_has_nested_ref();
00981 }
00982
00983 sym->Points_to()->Init();
00984 sym->Set_byte_size(byte_size);
00985 sym->Set_bit_ofst_size(bit_ofst, bit_size);
00986 sym->Set_ty(wn_object_ty);
00987 sym->Points_to()->Set_hl_ty(hl_ty);
00988
00989 INT64 tmpofst;
00990 ST *tmpbase;
00991 Expand_ST_into_base_and_ofst(st, ofst, &tmpbase, &tmpofst);
00992 sym->Set_base(tmpbase);
00993 sym->Set_base_byte_ofst(tmpofst);
00994 #ifdef KEY
00995 sym->Set_base_kind(BASE_IS_FIXED);
00996 #endif
00997
00998 if (WOPT_Set_Unique_Pt != NULL &&
00999 ST_name(st) != NULL &&
01000 strncmp(WOPT_Set_Unique_Pt, ST_name(st), strlen(WOPT_Set_Unique_Pt))
01001 == 0) {
01002
01003
01004
01005 Set_ST_pt_to_unique_mem(st);
01006 }
01007
01008
01009
01010 BOOL const_initialized = ST_is_const_initialized(st);
01011 if (const_initialized || (ST_is_initialized(st) &&
01012 ST_sclass(st) == SCLASS_PSTATIC)) {
01013 if (ST_is_const_initialized(st))
01014 sym->Set_const_init();
01015 INITV_IDX initv;
01016 if ((initv = ST_has_initv(st)) &&
01017 INITV_kind(Initv_Table[initv]) == INITVKIND_SYMOFF) {
01018 ST *st = &St_Table[INITV_st(Initv_Table[initv])];
01019 if (const_initialized || ST_class(st) == CLASS_VAR) {
01020 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
01021 fprintf(TFile, "Enter initv: %s+%d\n", ST_name(st),
01022 INITV_ofst(Initv_Table[initv]));
01023 }
01024 Enter_symbol(OPR_LDA, st, INITV_ofst(Initv_Table[initv]),
01025 ST_type(st), TY_is_volatile(ST_type(st)));
01026 }
01027 }
01028 }
01029 return idx;
01030 }
01031
01032
01033 AUX_ID
01034 OPT_STAB::Enter_ded_preg(ST *st, INT64 ofst, TY_IDX ty, INT32 mclass)
01035 {
01036 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_st_idx(st));
01037 AUX_ID idx;
01038 if (st_chain_info != NULL) {
01039 idx = st_chain_info->List_head();
01040 }
01041 else {
01042 idx = (AUX_ID) 0;
01043 }
01044
01045 while (idx && aux_stab[idx].St() != NULL) {
01046 Is_True(aux_stab[idx].St() == st,
01047 ("Enter_ded_preg::lookup wrong ST chain."));
01048 if (aux_stab[idx].Stype() == VT_NO_LDA_SCALAR &&
01049 aux_stab[idx].Mclass() == mclass &&
01050 aux_stab[idx].St_ofst() == ofst) {
01051 return idx;
01052 }
01053 idx = aux_stab[idx].St_chain();
01054 }
01055
01056
01057 if (idx == 0 || aux_stab[idx].St() != NULL) {
01058 idx = aux_stab.Newidx();
01059
01060
01061
01062
01063
01064
01065 if (st_chain_info == NULL) {
01066 st_chain_info = CXX_NEW(ST_CHAIN_INFO(0), &_st_chain_pool);
01067 st_chain_map->Insert(ST_st_idx(st), st_chain_info);
01068 }
01069 aux_stab[idx].Set_st_chain(st_chain_info->List_head());
01070 }
01071 else {
01072 aux_stab[idx].Set_st_chain((AUX_ID) 0);
01073 }
01074
01075
01076 st_chain_info->Set_list_head(idx);
01077
01078 AUX_STAB_ENTRY *sym = Aux_stab_entry(idx);
01079
01080 sym->Set_stype(VT_NO_LDA_SCALAR);
01081 sym->Set_mclass(mclass);
01082 sym->Set_mtype(MTYPE_UNKNOWN);
01083 #ifdef KEY
01084
01085 sym->Set_value_size(0);
01086 sym->Set_spre_node(NULL);
01087 #endif
01088 sym->Clear_flags();
01089 sym->Set_st(st);
01090 sym->Set_st_ofst(ofst);
01091 sym->Set_nonzerophis(NULL);
01092
01093 sym->Set_st_group((AUX_ID) 0);
01094 sym->Set_synonym((AUX_ID) 0);
01095 sym->Set_home_sym((AUX_ID) 0);
01096 sym->Set_zero_cr(NULL);
01097 sym->Points_to()->Analyze_ST(st, sym->St_ofst(), TY_size(ST_type(st)), 0,
01098 0, ty, FALSE );
01099
01100 return idx;
01101 }
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 AUX_ID
01117 OPT_STAB::Create_vsym(EXPR_KIND k)
01118 {
01119 AUX_ID retv = aux_stab.Newidx();
01120 AUX_STAB_ENTRY *vsym = Aux_stab_entry(retv);
01121 vsym->Set_stype(VT_SPECIAL_VSYM);
01122 vsym->Clear_flags();
01123 vsym->Set_mclass(0);
01124 vsym->Set_mtype(MTYPE_UNKNOWN);
01125 #ifdef KEY
01126
01127 vsym->Set_value_size(0);
01128 vsym->Set_spre_node(NULL);
01129 #endif
01130 vsym->Set_st(NULL);
01131 vsym->Set_st_ofst(0);
01132 vsym->Set_nonzerophis(NULL);
01133 vsym->Set_st_chain(0);
01134 vsym->Set_st_group(0);
01135 vsym->Set_aux_id_list(NULL);
01136 vsym->Set_def_bbs(NULL);
01137 vsym->Set_home_sym((AUX_ID) 0);
01138 vsym->Set_zero_cr(NULL);
01139 vsym->Points_to()->Init();
01140 vsym->Points_to()->Set_expr_kind(k);
01141 return retv;
01142 }
01143
01144
01145 AUX_ID
01146 OPT_STAB::Create_preg(MTYPE preg_ty, const char *name, WN *home_wn)
01147 {
01148 ST *st;
01149 #ifdef KEY // bug 1523: preopt in ipl cannot use pregs due to exception handling
01150 if ((Has_exc_handler() || Has_nonlocal_goto_target())
01151 && Phase() == PREOPT_IPA0_PHASE)
01152 st = Gen_Temp_Symbol(MTYPE_To_TY(preg_ty), name);
01153 else
01154 #endif
01155 st = MTYPE_To_PREG(preg_ty);
01156 AUX_ID retv = aux_stab.Newidx();
01157
01158 if (st_chain_map != NULL) {
01159 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_st_idx(st));
01160 if (st_chain_info != NULL) {
01161 aux_stab[retv].Set_st_chain(st_chain_info->List_head());
01162 }
01163 else {
01164 aux_stab[retv].Set_st_chain((AUX_ID) 0);
01165 }
01166 }
01167 AUX_STAB_ENTRY *sym = Aux_stab_entry(retv);
01168 sym->Set_stype(VT_NO_LDA_SCALAR);
01169 sym->Clear_flags();
01170 sym->Set_mclass(Get_mtype_class(preg_ty));
01171 sym->Set_mtype(preg_ty);
01172 sym->Set_st(st);
01173 #ifdef KEY // due to about change, st is no longer always preg
01174 if (ST_class(st) == CLASS_PREG)
01175 sym->Set_st_ofst(Alloc_preg(preg_ty,name,home_wn));
01176 else
01177
01178 sym->Set_st_ofst(0);
01179 #else
01180 sym->Set_st_ofst(Alloc_preg(preg_ty,name,home_wn));
01181 #endif
01182 sym->Set_nonzerophis(NULL);
01183 sym->Set_st_group(0);
01184 sym->Set_synonym((AUX_ID) 0);
01185 sym->Set_home_sym((AUX_ID) 0);
01186 sym->Set_zero_cr(NULL);
01187 #ifdef KEY
01188
01189 sym->Set_value_size(0);
01190 sym->Set_spre_node(NULL);
01191 #endif
01192
01193 sym->Set_def_bbs(NULL);
01194
01195 sym->Points_to()->Analyze_ST(st, sym->St_ofst(),
01196 TY_size(MTYPE_To_TY(preg_ty)), 0, 0, 0,
01197 FALSE );
01198 return retv;
01199 }
01200
01201
01202 void
01203 AUX_STAB_ENTRY::Change_to_new_preg(OPT_STAB *opt_stab, CODEMAP *htable)
01204 {
01205 Is_True(Cr_list(), ("AUX_STAB_ENTRY::Change_to_new_preg: Cr_list is NULL"));
01206
01207 BOOL was_formal = (ST_sclass(st) == SCLASS_FORMAL);
01208 MTYPE preg_ty = 0;
01209
01210 CODEREP *cr;
01211 CODEREP_ITER iter;
01212 FOR_ALL_NODE(cr, iter, Init(Cr_list())) {
01213 if (!cr->Is_flag_set(CF_MADEUP_TYPE)) {
01214 preg_ty = cr->Dtyp();
01215 break;
01216 }
01217 }
01218
01219 if (preg_ty == 0) return;
01220
01221
01222 const char * name = St_name();
01223 Set_st(MTYPE_To_PREG(preg_ty));
01224 Set_stype(VT_NO_LDA_SCALAR);
01225 #ifdef TARG_NVISA
01226
01227
01228 WN *home_wn = NULL;
01229 if (cr->Defstmt() && cr->Defstmt()->Rhs()) {
01230 home_wn = cr->Defstmt()->Rhs()->Rvi_home_wn(opt_stab);
01231 }
01232 mINT64 offset = opt_stab->Alloc_preg(preg_ty, name, home_wn);
01233 #else
01234 mINT64 offset = opt_stab->Alloc_preg(preg_ty,name);
01235 #endif
01236 Set_st_ofst(offset);
01237 Set_st_group(0);
01238 Set_synonym((AUX_ID) 0);
01239 Set_home_sym((AUX_ID) 0);
01240 Set_zero_cr(NULL);
01241
01242 Set_value_size(MTYPE_size_min(cr->Dsctyp()));
01243
01244 #ifdef Is_True_On
01245 BOOL is_sign_extd = cr->Is_sign_extd();
01246 cr->Set_sign_extension_flag();
01247 Is_True(is_sign_extd == cr->Is_sign_extd(),
01248 ("AUX_STAB_ENTRY::Change_to_new_preg: existing cr's sign"
01249 " extension flag is inconsistent"));
01250 #endif // Is_True_On
01251 if (cr->Is_sign_extd())
01252 Set_sign_extd();
01253 else
01254 Set_zero_extd();
01255
01256
01257 STMTREP *defstmt;
01258 CODEREP *rhs;
01259 FOLD ftmp;
01260 INT cvt_kind;
01261 OPCODE opc;
01262
01263 FOR_ALL_NODE(cr, iter, Init(Cr_list())) {
01264 cr->Set_offset(offset);
01265 Is_True(cr->Kind()==CK_VAR,
01266 ("AUX_STAB_ENTRY::Change_to_new_preg: cr is not CK_VAR"));
01267 if (!cr->Is_flag_set(CF_DEF_BY_CHI) &&
01268 (defstmt = cr->Defstmt()) != NULL &&
01269 (rhs = defstmt->Rhs()) != NULL){
01270 MTYPE dsctyp = cr->Dsctyp();
01271 MTYPE rhs_type = rhs->Dtyp();
01272 CODEREP *tmpcr = Alloc_stack_cr(0);
01273
01274 if ( MTYPE_is_integral(rhs_type) && MTYPE_is_integral(dsctyp) ) {
01275 if (WOPT_Enable_Min_Type &&
01276 (rhs->Kind() == CK_VAR ||
01277 (rhs->Kind() == CK_IVAR && rhs->Ivar_has_e_num())) &&
01278 MTYPE_size_min(dsctyp) == MTYPE_size_min(rhs->Dsctyp()) &&
01279 cr->Is_sign_extd() == rhs->Is_sign_extd())
01280 continue;
01281 cvt_kind = NOT_AT_ALL;
01282 if ( MTYPE_size_min(dsctyp) < MTYPE_size_min(rhs_type) ) {
01283
01284 cvt_kind = Need_type_conversion(rhs_type, dsctyp, &opc);
01285 if (WOPT_Enable_Min_Type &&
01286 rhs->Kind() == CK_VAR &&
01287 No_truncation_by_value_size(dsctyp, Is_sign_extd(), rhs,
01288 htable->Sym()))
01289 cvt_kind = NOT_AT_ALL;
01290 else if (!Only_Unsigned_64_Bit_Ops &&
01291 was_formal &&
01292 (Language == LANG_CPLUS || Language == LANG_ANSI_C) &&
01293 #ifdef KEY
01294 opt_stab->Is_prototyped_func() &&
01295 #endif
01296 MTYPE_is_signed(dsctyp) == MTYPE_is_signed(rhs_type) &&
01297 rhs->Kind() == CK_VAR &&
01298 opt_stab->Aux_stab_entry(rhs->Aux_id())->Is_dedicated_preg())
01299 cvt_kind = NOT_AT_ALL;
01300 }
01301 } else {
01302 cvt_kind = Need_type_conversion(rhs_type, dsctyp, &opc);
01303 }
01304
01305 switch ( cvt_kind ) {
01306 case NOT_AT_ALL:
01307 break;
01308 case NEED_CVT:
01309 if ( (opc == OPC_U4U8CVT || opc == OPC_U4I8CVT) &&
01310 cr->Dtyp() == MTYPE_U8 ) {
01311 opc = OPC_U8CVTL;
01312 tmpcr->Init_expr(opc, rhs);
01313 tmpcr->Set_offset(MTYPE_size_min(dsctyp));
01314 rhs = ftmp.Fold_Expr(tmpcr);
01315 if (!rhs) {
01316 rhs = htable->Rehash(tmpcr);
01317
01318 }
01319 } else {
01320 tmpcr->Init_expr(opc,rhs);
01321 rhs = ftmp.Fold_Expr(tmpcr);
01322 if (!rhs) {
01323 rhs = htable->Rehash(tmpcr);
01324
01325 }
01326 }
01327 break;
01328 case NEED_CVTL:
01329 tmpcr->Init_expr(opc,rhs);
01330 tmpcr->Set_offset(MTYPE_size_min(dsctyp));
01331 rhs = ftmp.Fold_Expr(tmpcr);
01332 if (!rhs) {
01333 rhs = htable->Rehash(tmpcr);
01334
01335 }
01336 }
01337 defstmt->Set_rhs(rhs);
01338 }
01339 }
01340
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369 void
01370 Get_symbol_info_for_cvt_io( POINTS_TO *points_to, WN *wn )
01371 {
01372 const OPERATOR opr = WN_operator(wn);
01373
01374 Is_True ( OPERATOR_has_aux(opr) && WN_st(wn) != NULL,
01375 ("Get_symbol_info_for_cvt_io: %s has no symbol",
01376 OPERATOR_name(opr)) );
01377
01378 ST *st = WN_st(wn);
01379 TY_IDX ty = ST_type(st);
01380 INT64 ofst = WN_offset(wn);
01381 switch ( opr ) {
01382 case OPR_IDNAME:
01383 case OPR_LDA:
01384 case OPR_LDID:
01385 case OPR_STID:
01386 {
01387 INT64 size = 0;
01388 if ( opr == OPR_IDNAME || opr == OPR_LDA )
01389 size = TY_size(ty);
01390 else if (WN_desc(wn) == MTYPE_M)
01391 size = Desc_type_byte_size(wn);
01392 else
01393 size = MTYPE_size_min(WN_desc(wn)) >> 3;
01394 points_to->Analyze_ST(st, ofst, size, 0, 0, ty,
01395 TRUE );
01396 }
01397 break;
01398 case OPR_LDBITS:
01399 case OPR_STBITS:
01400 points_to->Analyze_ST(st, ofst, MTYPE_size_min(WN_desc(wn)) >> 3,
01401 WN_bit_offset (wn), WN_bit_size (wn), ty, TRUE);
01402 break;
01403 default:
01404 points_to->Init();
01405 }
01406 }
01407
01408
01409 void
01410 OPT_STAB::Process_varfmt_for_cvt_io( WN *iown )
01411 {
01412 AUX_ID idx;
01413 AUX_STAB_ITER aux_stab_iter(this);
01414
01415 FOR_ALL_NODE(idx, aux_stab_iter, Init()) {
01416 AUX_STAB_ENTRY *psym = Aux_stab_entry(idx);
01417
01418 if ( ! psym->Has_nested_ref() )
01419 continue;
01420
01421 ST *st = psym->St();
01422 TY_IDX ty = ST_type(st);
01423
01424 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
01425 fprintf( TFile, "Process_varfmt_for_cvt_io: refs:%s\n",
01426 ST_name(st) );
01427 }
01428
01429
01430 POINTS_TO *points_to = CXX_NEW(POINTS_TO,mem_pool);
01431 points_to->Analyze_ST(st, 0, TY_size(ty), 0, 0, ty,
01432 TRUE );
01433
01434
01435 Add_black_box_ref( iown, points_to );
01436 Add_black_box_def( iown, points_to );
01437 }
01438 }
01439
01440
01441 void
01442 OPT_STAB::Convert_IO_statement( WN *iown, WN *wn, INT level )
01443 {
01444 const OPERATOR opr = WN_operator(wn);
01445
01446 Is_True( opr == OPR_IO || level > 0,
01447 ("OPT_STAB::Convert_IO_statement: Not an IO statement: %s",
01448 OPERATOR_name(opr)) );
01449
01450 if ( OPERATOR_has_aux(opr)) {
01451 ST *st = WN_st(wn);
01452
01453
01454 if (ST_class(st) != CLASS_VAR)
01455 goto has_sym_end;
01456
01457
01458 POINTS_TO *points_to = CXX_NEW(POINTS_TO,mem_pool);
01459 Get_symbol_info_for_cvt_io( points_to, wn );
01460
01461 Warn_todo( "OPT_STAB::Convert_IO_statement: deal with Fortran pointer.");
01462 if (OPERATOR_is_load(opr) || opr == OPR_LDA)
01463 Add_black_box_ref( iown, points_to );
01464
01465 if (OPERATOR_is_store(opr) || opr == OPR_LDA)
01466 Add_black_box_def( iown, points_to );
01467
01468 if (opr == OPR_LDID &&
01469 IS_FORTRAN &&
01470 ST_sclass(st) == SCLASS_FORMAL &&
01471 !ST_is_value_parm(st)) {
01472 POINTS_TO *points_to = CXX_NEW(POINTS_TO,mem_pool);
01473 points_to->Analyze_ST_as_base(st, WN_offset(wn), WN_object_ty(wn));
01474 Add_black_box_ref( iown, points_to );
01475 Add_black_box_def( iown, points_to );
01476 }
01477
01478 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
01479 fprintf( TFile, "Convert_IO_statement: refs:%s\n", ST_name(st) );
01480 }
01481 }
01482 has_sym_end:
01483
01484
01485
01486
01487 if ( opr == OPR_IO_ITEM && int(WN_intrinsic(wn)) == int(IOC_VARFMT) ) {
01488 Is_True( WN_operator(WN_kid0(wn)) == OPR_LDA,
01489 ("VARFMT without LDA") );
01490
01491 Process_varfmt_for_cvt_io( iown );
01492 }
01493
01494
01495 for ( INT i = 0; i < WN_kid_count(wn); i++ )
01496 Convert_IO_statement( iown, WN_kid(wn,i), level+1 );
01497 }
01498
01499
01500 void
01501 OPT_STAB::Convert_black_box( WN *wn )
01502 {
01503 switch ( WN_operator(wn) ) {
01504 case OPR_IO:
01505 Convert_IO_statement( wn, wn, 0 );
01506 break;
01507 default:
01508 FmtAssert( FALSE,("OPT_STAB::Convert_black_box: Unknown opcode: %s",
01509 OPERATOR_name(WN_operator(wn))) );
01510 break;
01511 }
01512 }
01513
01514
01515
01516
01517
01519 static ST *
01520 MTYPE_To_Dedicated_PREG( TYPE_ID mtype )
01521 {
01522 switch ( mtype ) {
01523 case MTYPE_I1:
01524 case MTYPE_I2:
01525 case MTYPE_I4:
01526 case MTYPE_U1:
01527 case MTYPE_U2:
01528 case MTYPE_U4:
01529 return MTYPE_To_PREG( MTYPE_I4 );
01530 case MTYPE_I8:
01531 case MTYPE_U8:
01532 return MTYPE_To_PREG( MTYPE_I8 );
01533 default:
01534 return MTYPE_To_PREG( mtype );
01535 }
01536 }
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 void
01557 OPT_STAB::Convert_ST_to_AUX(WN *wn, WN *block_wn)
01558 {
01559 INT32 i;
01560 WN *stmt;
01561 AUX_ID idx;
01562
01563 if (wn == NULL)
01564 return;
01565
01566 OPERATOR opr = WN_operator(wn);
01567 TYPE_ID rtype = WN_rtype(wn);
01568 TYPE_ID desc = WN_desc(wn);
01569
01570
01571
01572
01573 if (opr == OPR_CALL || opr == OPR_ICALL || opr == OPR_INTRINSIC_CALL) {
01574 PREG_NUM retreg[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
01575 TYPE_ID ty[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
01576 #ifdef TARG_X8664
01577 ST *call_st = NULL;
01578 if (opr == OPR_CALL)
01579 call_st = WN_st(wn);
01580 #endif
01581
01582 ty[0] = MTYPE_V;
01583 ty[1] = MTYPE_V;
01584
01585
01586 if (WHIRL_Return_Info_On) {
01587
01588 RETURN_INFO return_info = Get_Return_Info (
01589 MTYPE_To_TY(rtype),
01590 Allow_sim_type() ? Use_Simulated
01591 : Complex_Not_Simulated
01592 #ifdef TARG_X8664
01593 , call_st ? PU_ff2c_abi(Pu_Table[ST_pu(call_st)]) : FALSE
01594 #endif
01595 );
01596
01597 if (RETURN_INFO_count(return_info)
01598 <= MAX_NUMBER_OF_REGISTERS_FOR_RETURN)
01599 {
01600 for (i = 0; i < RETURN_INFO_count(return_info); i++) {
01601 ty[i] = RETURN_INFO_mtype (return_info, i);
01602 retreg[i] = RETURN_INFO_preg (return_info, i);
01603 }
01604 }
01605
01606 else
01607 Fail_FmtAssertion ("OPT_STAB::Convert_ST_to_AUX: more than %d return"
01608 " registers", MAX_NUMBER_OF_REGISTERS_FOR_RETURN);
01609 }
01610
01611 else {
01612 Get_Return_Mtypes(MTYPE_To_TY(rtype),
01613 (Allow_sim_type() ? Use_Simulated
01614 : Complex_Not_Simulated), &ty[0], &ty[1]);
01615 Get_Return_Pregs(ty[0], ty[1], &retreg[0], &retreg[1]);
01616 }
01617
01618 if (ty[0] != MTYPE_V) {
01619 Enter_ded_preg(MTYPE_To_Dedicated_PREG(rtype),
01620 retreg[0],
01621 MTYPE_To_TY(rtype),
01622 Get_mtype_class(ty[0]));
01623
01624 ty[0] = MTYPE_V;
01625 ty[1] = MTYPE_V;
01626
01627
01628 if (WHIRL_Return_Info_On) {
01629
01630 RETURN_INFO return_info = Get_Return_Info (
01631 MTYPE_To_TY(desc),
01632 Allow_sim_type() ? Use_Simulated
01633 : Complex_Not_Simulated
01634 #ifdef TARG_X8664
01635 , call_st ? PU_ff2c_abi(Pu_Table[ST_pu(call_st)]) : FALSE
01636 #endif
01637 );
01638
01639 if (RETURN_INFO_count(return_info)
01640 <= MAX_NUMBER_OF_REGISTERS_FOR_RETURN)
01641 {
01642 for (i = 0; i < RETURN_INFO_count(return_info); i++) {
01643 ty[i] = RETURN_INFO_mtype (return_info, i);
01644 retreg[i] = RETURN_INFO_preg (return_info, i);
01645 }
01646 }
01647
01648 else
01649 Fail_FmtAssertion ("OPT_STAB::Convert_ST_to_AUX: more than %d return"
01650 " registers", MAX_NUMBER_OF_REGISTERS_FOR_RETURN);
01651 }
01652
01653 else {
01654 Get_Return_Mtypes(MTYPE_To_TY(desc),
01655 (Allow_sim_type() ? Use_Simulated
01656 : Complex_Not_Simulated), &ty[0], &ty[1]);
01657 Get_Return_Pregs(ty[0], ty[1], &retreg[0], &retreg[1]);
01658 }
01659 if (ty[0] != MTYPE_V) {
01660 Enter_ded_preg(MTYPE_To_Dedicated_PREG(desc),
01661 retreg[0],
01662 MTYPE_To_TY(desc),
01663 Get_mtype_class(ty[0]));
01664 }
01665 }
01666 }
01667
01668 if (opr == OPR_FUNC_ENTRY || opr == OPR_ALTENTRY) {
01669 PREG_NUM retreg[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
01670 TYPE_ID ty[MAX_NUMBER_OF_REGISTERS_FOR_RETURN];
01671
01672 ty[0] = MTYPE_V;
01673 ty[1] = MTYPE_V;
01674
01675 TY_IDX ret_ty = TY_ret_type(ST_pu_type(WN_st(wn)));
01676
01677 if (WHIRL_Return_Info_On) {
01678
01679 RETURN_INFO return_info = Get_Return_Info (
01680 ret_ty,
01681 Allow_sim_type() ? Use_Simulated
01682 : Complex_Not_Simulated
01683 #ifdef TARG_X8664
01684 , PU_ff2c_abi(Pu_Table[ST_pu(WN_st(wn))])
01685 #endif
01686 );
01687
01688 if (RETURN_INFO_count(return_info)
01689 <= MAX_NUMBER_OF_REGISTERS_FOR_RETURN)
01690 {
01691 for (i = 0; i < RETURN_INFO_count(return_info); i++) {
01692 ty[i] = RETURN_INFO_mtype (return_info, i);
01693 retreg[i] = RETURN_INFO_preg (return_info, i);
01694 }
01695 }
01696
01697 else
01698 Fail_FmtAssertion ("OPT_STAB::Convert_ST_to_AUX: more than %d return"
01699 " registers", MAX_NUMBER_OF_REGISTERS_FOR_RETURN);
01700 }
01701
01702 else {
01703 Get_Return_Mtypes(ret_ty,
01704 (Allow_sim_type() ? Use_Simulated
01705 : Complex_Not_Simulated), &ty[0], &ty[1]);
01706 Get_Return_Pregs(ty[0], ty[1], &retreg[0], &retreg[1]);
01707 }
01708 if (ty[0] != MTYPE_V) {
01709
01710 idx = Enter_ded_preg(MTYPE_To_Dedicated_PREG(ty[0]), retreg[0],
01711 MTYPE_To_TY(ty[0]), Get_mtype_class(ty[0]));
01712 if (ty[1] != MTYPE_V) {
01713 idx = Enter_ded_preg(MTYPE_To_Dedicated_PREG(ty[1]), retreg[1],
01714 MTYPE_To_TY(ty[1]), Get_mtype_class(ty[1]));
01715 }
01716 }
01717 }
01718
01719
01720 if (WOPT_Enable_Simp_Iload) {
01721 if (OPERATOR_is_scalar_iload (opr)) {
01722 WN *twn = WN_SimplifyIload(OPCODE_make_op(opr, rtype, desc),
01723 WN_load_offset(wn), WN_ty(wn),
01724 WN_field_id(wn), WN_load_addr_ty(wn),
01725 WN_kid0(wn));
01726 if (twn) {
01727 opr = WN_operator(twn);
01728 rtype = WN_rtype(twn);
01729 desc = WN_desc(twn);
01730 WN_set_operator(wn, opr);
01731 WN_set_rtype(wn, rtype);
01732 WN_set_desc(wn, desc);
01733 WN_load_offset(wn) = WN_load_offset(twn);
01734 WN_st_idx(wn) = WN_st_idx(twn);
01735 WN_set_ty(wn, WN_ty(twn));
01736 WN_kid0(wn) = NULL;
01737 WN_Delete(twn);
01738 }
01739 }
01740 else if (OPERATOR_is_scalar_istore (opr)) {
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752 WN *twn = WN_SimplifyIstore(OPCODE_make_op(opr, rtype, desc),
01753 WN_load_offset(wn), WN_ty(wn),
01754 WN_field_id(wn), WN_kid0(wn), WN_kid1(wn));
01755 if (twn) {
01756 opr = WN_operator(twn);
01757 rtype = WN_rtype(twn);
01758 desc = WN_desc(twn);
01759 WN_set_operator(wn, opr);
01760 WN_set_rtype(wn, rtype);
01761 WN_set_desc(wn, desc);
01762 WN_load_offset(wn) = WN_load_offset(twn);
01763 WN_st_idx(wn) = WN_st_idx(twn);
01764 WN_set_ty(wn, WN_ty(twn));
01765 WN_kid0(wn) = WN_kid0(twn);
01766 WN_Delete(twn);
01767 }
01768 }
01769 }
01770
01771 if (Phase() == MAINOPT_PHASE &&
01772 Only_Unsigned_64_Bit_Ops &&
01773 ! Delay_U64_Lowering) {
01774 if ((OPERATOR_is_scalar_load (opr) && WN_class(wn) != CLASS_PREG ||
01775 opr == OPR_ILOAD) &&
01776 MTYPE_is_integral(rtype))
01777 Is_True(MTYPE_size_min(rtype) == 64 &&
01778 (MTYPE_size_min(desc) == 64 || !MTYPE_signed(desc)) ||
01779 MTYPE_size_min(desc) == 64 && MTYPE_size_min(rtype) == 32,
01780 ("Convert_ST_to_AUX: illegal types in load instruction."));
01781 }
01782
01783
01784 if ((opr == OPR_TRUEBR || opr == OPR_FALSEBR) &&
01785 WN_operator(WN_kid0(wn)) == OPR_INTCONST) {
01786 WN *test = WN_kid0(wn);
01787 if (opr == OPR_TRUEBR && WN_const_val(test) != 0 ||
01788 opr == OPR_FALSEBR && WN_const_val(test) == 0) {
01789 WN_Delete(test);
01790 WN_set_operator(wn, OPR_GOTO);
01791 WN_set_rtype(wn, MTYPE_V);
01792 WN_set_desc(wn, MTYPE_V);
01793 WN_set_kid_count(wn, 0);
01794 WN_kid0(wn) = NULL;
01795 WN_st_idx(wn) = (ST_IDX) 0;
01796
01797 if ( Cur_PU_Feedback )
01798 Cur_PU_Feedback->FB_simplify_branch_to_goto( wn );
01799 }
01800 }
01801
01802
01803 if (opr == OPR_LDA) {
01804 ST *st = WN_st(wn);
01805 if (ST_class(st) == CLASS_VAR) {
01806
01807 Set_BE_ST_addr_used_locally(st);
01808 }
01809 }
01810
01811 if (OPERATOR_has_aux(opr)) {
01812 ST *st = WN_st(wn);
01813 idx = Enter_symbol(WN_operator(wn), st, WN_offset(wn), WN_object_ty(wn),
01814 Check_volatility (wn, st), wn);
01815 Is_True(idx != 0, ("Convert_ST_to_AUX: index is 0."));
01816 WN_set_aux(wn, idx);
01817 }
01818
01819
01820 if (opr == OPR_REGION) {
01821 RID *rid = REGION_get_rid(wn);
01822 Is_True(rid != NULL,("OPT_STAB::Convert_ST_to_AUX, NULL rid"));
01823 Is_True(REGION_consistency_check(wn),("OPT_STAB::Convert_ST_to_AUX"));
01824 if (RID_level(rid) >= Rgn_level()) {
01825 if (_rgn_trace)
01826 fprintf(TFile,"OPT_STAB::Convert_ST_to_AUX, skipping previously "
01827 "processed RGN %d, %s\n", RID_id(rid),RID_level_str(rid));
01828 return;
01829 }
01830 #ifdef KEY
01831 BOOL has_parallel_pragma = FALSE;
01832 BOOL in_parallel_region_save = FALSE;
01833 if (Phase() != MAINOPT_PHASE && PU_has_mp(Get_Current_PU()) &&
01834 ! PU_mp_lower_generated(Get_Current_PU())) {
01835 has_parallel_pragma = Is_region_with_pragma(wn, WN_PRAGMA_MASTER_BEGIN);
01836 }
01837 for (i = 0; i < WN_kid_count(wn); i++) {
01838 if (has_parallel_pragma && i == 2) {
01839 in_parallel_region_save = in_parallel_region;
01840 in_parallel_region = TRUE;
01841 }
01842 Convert_ST_to_AUX(WN_kid(wn,i), NULL);
01843 if (has_parallel_pragma && i == 2)
01844 in_parallel_region = in_parallel_region_save;
01845 }
01846 return;
01847 #endif
01848 }
01849
01850 if (opr == OPR_ASM_STMT) {
01851
01852 WN *prag = WN_first(WN_asm_constraints(wn));
01853 while (prag != NULL) {
01854 FmtAssert(WN_pragma(prag) == WN_PRAGMA_ASM_CONSTRAINT,
01855 ("Unknown pragma type for ASM output constraint"));
01856 AUX_ID idx = Enter_ded_preg(WN_st(prag),
01857 WN_pragma_asm_copyout_preg(prag),
01858 ST_type(WN_st(prag)),
01859 Get_mtype_class(TY_mtype(ST_type(WN_st(prag)))));
01860 WN_set_aux(prag, idx);
01861 prag = WN_next(prag);
01862 }
01863 }
01864
01865 if (opr == OPR_BLOCK) {
01866 for (stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))
01867 Convert_ST_to_AUX(stmt, wn);
01868 }
01869 else if (OPERATOR_is_black_box(opr)) {
01870
01871
01872 Convert_black_box( wn );
01873 }
01874 else {
01875 for (i = 0; i < WN_kid_count(wn); i++) {
01876 Convert_ST_to_AUX(WN_kid(wn,i), NULL);
01877 }
01878
01879
01880 if (opr == OPR_DO_LOOP) {
01881 WN *init_stmt = WN_start(wn);
01882 Is_True(WN_operator(init_stmt) == OPR_STID,
01883 ("bad DO-loop init statement."));
01884 AUX_ID aux = WN_aux(init_stmt);
01885 aux_stab[aux].Set_loop_index();
01886 }
01887 }
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 static INT32
01911 cmp_ofst(AUX_STAB_ENTRY **t1, AUX_STAB_ENTRY **t2)
01912 {
01913 INT64 ofst1 = (*t1)->Base_byte_ofst() * 8 + (*t1)->Bit_ofst();
01914 INT64 ofst2 = (*t2)->Base_byte_ofst() * 8 + (*t2)->Bit_ofst();
01915 if (ofst1 < ofst2)
01916 return -1;
01917 else if (ofst1 > ofst2)
01918 return 1;
01919 else
01920 return 0;
01921 }
01922
01923
01924 void
01925 OPT_STAB::Make_st_group(void)
01926 {
01927 AUX_ID idx, group;
01928 ST *base;
01929 AUX_STAB_ITER aux_stab_iter(this);
01930 MEM_POOL tmp_pool;
01931
01932
01933
01934 FOR_ALL_NODE(idx, aux_stab_iter, Init()) {
01935
01936 ST *st = aux_stab[idx].St();
01937 if (st == NULL)
01938 continue;
01939
01940 if (ST_class(st) != CLASS_VAR) {
01941
01942
01943 continue;
01944 }
01945
01946 if (ST_sclass(aux_stab[idx].St()) == SCLASS_REG)
01947 continue;
01948
01949 base = aux_stab[idx].Base();
01950
01951
01952
01953
01954 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_st_idx(base));
01955 if (st_chain_info == NULL) {
01956 st_chain_info = CXX_NEW(ST_CHAIN_INFO(idx), &_st_chain_pool);
01957 st_chain_map->Insert(ST_st_idx(base), st_chain_info);
01958 group = idx;
01959 }
01960 else {
01961 group = st_chain_info->List_head();
01962 Is_True(group != (AUX_ID) 0,
01963 ("OPT_STAB::Make_st_group: Inconsistent st_chain_info"));
01964 }
01965
01966
01967 if (group != idx) {
01968 aux_stab[idx].Set_st_group(aux_stab[group].St_group());
01969 aux_stab[group].Set_st_group(idx);
01970 }
01971 }
01972
01973
01974
01975
01976
01977
01978 OPT_POOL_Initialize(&tmp_pool, "Temp used in OPT_STAB::Make_st_group",
01979 FALSE, MEM_DUMP_FLAG+10);
01980 OPT_POOL_Push(&tmp_pool, MEM_DUMP_FLAG+10);
01981
01982 AUX_STAB_ENTRY **sorted = (AUX_STAB_ENTRY **)
01983 OPT_POOL_Alloc(&tmp_pool, aux_stab.Lastidx() * sizeof(AUX_STAB_ENTRY *),
01984 MEM_DUMP_FLAG+10);
01985
01986 FOR_ALL_NODE(idx, aux_stab_iter, Init()) {
01987
01988
01989 if (aux_stab[idx].St() == NULL ||
01990 ST_class(aux_stab[idx].St()) != CLASS_VAR)
01991 continue;
01992
01993
01994 if (ST_sclass(aux_stab[idx].St()) == SCLASS_REG) {
01995 aux_stab[idx].Set_st_group(0);
01996 continue;
01997 }
01998
01999 base = aux_stab[idx].Base();
02000 ST_CHAIN_INFO *st_chain_info = st_chain_map->Lookup(ST_st_idx(base));
02001 Is_True(st_chain_info != NULL,
02002 ("OPT_STAB::Make_st_group: Inconsistent st_chain_map"));
02003 group = st_chain_info->List_head();
02004 Is_True(group != (AUX_ID) 0,
02005 ("OPT_STAB::Make_st_group: Inconsistent st_chain_info"));
02006
02007 if (group != idx) continue;
02008
02009 if ( aux_stab[group].St_group() ) {
02010 INT32 count = 0;
02011 while ( group ) {
02012 sorted[count++] = &aux_stab[group];
02013 group = aux_stab[group].St_group();
02014 }
02015 Is_True( count > 1, ("count must be > 1."));
02016
02017
02018 qsort(sorted, count, sizeof(AUX_STAB_ENTRY *),
02019 (INT32 (*)(const void *, const void *)) cmp_ofst);
02020
02021
02022
02023
02024
02025
02026
02027
02028 if (WOPT_Enable_Improved_Addr_Taken) {
02029 INT64 addr_used_high = sorted[0]->Base_byte_ofst() - 1;
02030 INT64 addr_saved_high = sorted[0]->Base_byte_ofst() - 1;
02031 INT64 addr_passed_high = sorted[0]->Base_byte_ofst() - 1;
02032 for (INT32 j = 0; j < count; j++) {
02033 INT64 upper = sorted[j]->Base_byte_ofst();
02034 if (sorted[j]->Byte_size() > 0)
02035 upper = sorted[j]->Base_byte_ofst() + sorted[j]->Byte_size() - 1;
02036 else {
02037 TY_IDX ty = ST_type(sorted[j]->St());
02038 if (ty != 0 && TY_kind(ty) == KIND_ARRAY)
02039 upper = LONG_MAX;
02040 }
02041
02042
02043 if (BE_ST_addr_used_locally(sorted[j]->St())) {
02044 if (upper > addr_used_high)
02045 addr_used_high = upper;
02046 }
02047 else {
02048
02049 if (sorted[j]->Base_byte_ofst() <= addr_used_high)
02050 Set_BE_ST_addr_used_locally(sorted[j]->St());
02051 else {
02052
02053 for (INT32 k = j + 1; k < count; k++) {
02054 if (sorted[k]->Base_byte_ofst() > upper) break;
02055 if (BE_ST_addr_used_locally(sorted[k]->St())) {
02056 Set_BE_ST_addr_used_locally(sorted[j]->St());
02057 break;
02058 }
02059 }
02060 }
02061 }
02062
02063
02064 if (ST_addr_saved(sorted[j]->St())) {
02065 if (upper > addr_saved_high)
02066 addr_saved_high = upper;
02067 } else {
02068
02069 if (sorted[j]->Base_byte_ofst() <= addr_saved_high) {
02070 Set_ST_addr_saved(sorted[j]->St());
02071 }
02072 else
02073
02074 for (INT32 k = j + 1; k < count; k++) {
02075 if (sorted[k]->Base_byte_ofst() > upper) break;
02076 if (ST_addr_saved(sorted[k]->St())) {
02077 Set_ST_addr_saved(sorted[j]->St());
02078 break;
02079 }
02080 }
02081 }
02082
02083
02084 if (BE_ST_addr_passed(sorted[j]->St())) {
02085 if (upper > addr_passed_high)
02086 addr_passed_high = upper;
02087 } else {
02088
02089 if (sorted[j]->Base_byte_ofst() <= addr_passed_high) {
02090 Set_BE_ST_addr_passed(sorted[j]->St());
02091 }
02092 else
02093
02094 for (INT32 k = j + 1; k < count; k++) {
02095 if (sorted[k]->Base_byte_ofst() > upper) break;
02096 if (BE_ST_addr_passed(sorted[k]->St())) {
02097 Set_BE_ST_addr_passed(sorted[j]->St());
02098 break;
02099 }
02100 }
02101 }
02102 }
02103 }
02104
02105
02106 INT32 count_var = 0;
02107 for (INT32 j = 0; j < count; j++) {
02108 #ifndef KEY // cannot remove virtual variables because Lower_to_extract_compose
02109
02110 if (sorted[j]->Is_real_var())
02111 #endif
02112 sorted[count_var++] = sorted[j];
02113 }
02114
02115
02116 INT64 low = sorted[0]->Base_byte_ofst() * 8 +
02117 sorted[0]->Bit_ofst();
02118 INT64 hi = low + (sorted[0]->Bit_size() == 0 ?
02119 sorted[0]->Byte_size() * 8 :
02120 sorted[0]->Bit_size());
02121 AUX_ID st_group_head = aux_stab.Idx(sorted[0]);
02122 AUX_ID st_group_tail = st_group_head;
02123 aux_stab[st_group_tail].Set_st_group(0);
02124
02125 for (INT32 i = 1; i < count_var; i++) {
02126 INT64 ofst = sorted[i]->Base_byte_ofst() * 8 + sorted[i]->Bit_ofst();
02127 Is_True( ofst >=
02128 sorted[i-1]->Base_byte_ofst() * 8 + sorted[i-1]->Bit_ofst(),
02129 ("Make_st_group: bad sorting."));
02130 UINT64 size = sorted[i]->Bit_size() == 0 ?
02131 sorted[i]->Byte_size() * 8 : sorted[i]->Bit_size();
02132 if (ofst < hi) {
02133 #if defined(linux) || defined(BUILD_OS_DARWIN)
02134
02135 if (hi < ofst + size)
02136 hi = ofst + size;
02137 #else
02138 hi = max(hi, (INT64) (ofst + size));
02139 #endif
02140 AUX_ID new_tail = aux_stab.Idx(sorted[i]);
02141 aux_stab[st_group_tail].Set_st_group( new_tail );
02142 aux_stab[new_tail].Set_st_group(st_group_head);
02143 st_group_tail = new_tail;
02144 } else {
02145
02146 low = ofst;
02147 hi = low + size;
02148 st_group_head = st_group_tail = aux_stab.Idx(sorted[i]);
02149 aux_stab[st_group_tail].Set_st_group(0);
02150 }
02151 }
02152 }
02153 }
02154
02155 OPT_POOL_Pop( &tmp_pool, MEM_DUMP_FLAG+10 );
02156 OPT_POOL_Delete ( &tmp_pool, MEM_DUMP_FLAG+10 );
02157 }
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 BOOL
02186 AUX_STAB_ENTRY::Equivalent(AUX_STAB_ENTRY *sym)
02187 {
02188 if (this->Base() == sym->Base() &&
02189 this->Base_byte_ofst() == sym->Base_byte_ofst() &&
02190 this->Byte_size() == sym->Byte_size() &&
02191 this->Bit_ofst() == sym->Bit_ofst() &&
02192 this->Bit_size() == sym->Bit_size() &&
02193 this->Mclass() == sym->Mclass() &&
02194 this->Field_id() == sym->Field_id())
02195 return TRUE;
02196 return FALSE;
02197 }
02198
02199
02200 BOOL
02201 Completely_replaced(AUX_STAB_ENTRY *psym)
02202 {
02203 if (psym->Is_real_var() &&
02204 !psym->Is_virtual() &&
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216 !psym->Loop_index() &&
02217
02218
02219
02220 (psym->Points_to()->Ip_alias_class() != PESSIMISTIC_AC_ID) &&
02221 psym->Synonym())
02222 return TRUE;
02223 else
02224 return FALSE;
02225 }
02226
02227
02228 void
02229 OPT_STAB::Remap_aux_synonym(WN *wn)
02230 {
02231 INT32 i;
02232
02233 if (wn == NULL) return;
02234 const OPERATOR opr = WN_operator(wn);
02235
02236
02237 if ( OPERATOR_has_aux(opr)) {
02238
02239 AUX_ID idx = WN_aux(wn);
02240 if (Completely_replaced(Aux_stab_entry(idx))) {
02241 AUX_ID syn = aux_stab[idx].Synonym();
02242 WN_set_aux(wn, syn);
02243 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG))
02244 fprintf(TFile, "remap auxid %d to %d\n", idx, syn);
02245 WN_offset(wn) = aux_stab[syn].St_ofst();
02246 }
02247 }
02248
02249
02250
02251 if (opr == OPR_REGION) {
02252 RID *rid = REGION_get_rid(wn);
02253 Is_True(rid != NULL, ("OPT_STAB::Remap_aux_synonym, NULL rid"));
02254 if (RID_level(rid) >= Rgn_level())
02255 return;
02256 }
02257 if (opr == OPR_BLOCK) {
02258 for (WN *stmt = WN_first(wn); stmt != NULL; stmt = WN_next(stmt))
02259 Remap_aux_synonym(stmt);
02260 }
02261 else if ( !OPERATOR_is_black_box( opr ) ) {
02262 for (i = 0; i < WN_kid_count(wn); i++)
02263 Remap_aux_synonym(WN_kid(wn, i));
02264 }
02265 }
02266
02267
02268 void
02269 OPT_STAB::Canonicalize(void)
02270 {
02271 AUX_ID idx, cur;
02272 AUX_STAB_ITER aux_stab_iter(this);
02273
02274
02275 FOR_ALL_NODE(idx, aux_stab_iter, Init()) {
02276 if (!aux_stab[idx].Is_real_var())
02277 continue;
02278 if (cur = aux_stab[idx].St_group()) {
02279 AUX_ID min = idx;
02280 while (cur && cur != idx) {
02281 if (min > cur && aux_stab[idx].Equivalent(&aux_stab[cur])) {
02282 min = cur;
02283 }
02284 cur = aux_stab[cur].St_group();
02285 }
02286 if (min != idx) {
02287 aux_stab[idx].Set_synonym(min);
02288 } else {
02289 aux_stab[idx].Set_synonym(0);
02290 }
02291 }
02292 }
02293
02294
02295 Remap_aux_synonym(pu_wn);
02296 }
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330 void OPT_STAB::Update_attr_cache(AUX_ID idx, ST *st, POINTS_TO *pt,
02331 BOOL *has_weak_var)
02332 {
02333
02334 if (WOPT_Enable_Update_Vsym && aux_stab[idx].Is_virtual())
02335 Set_virtual_var(idx);
02336
02337 if (st == NULL) {
02338
02339 Set_addr_used_locally(idx);
02340 Set_external(idx);
02341
02342 } else {
02343
02344
02345 if (!pt->Not_addr_saved())
02346 Set_addr_saved(idx);
02347 if (!pt->Not_addr_passed())
02348 Set_addr_passed(idx);
02349 if (pt->Global())
02350 Set_external(idx);
02351 if (pt->Formal() && IS_FORTRAN && !ST_is_value_parm(st))
02352 Set_ref_formal(idx);
02353 #ifdef KEY
02354 if (pt->Const()) {
02355 if (ST_is_initialized(st)) {
02356 aux_stab[idx].Set_const_init();
02357 }
02358 #else
02359 if (pt->Const())
02360 #endif
02361 Set_const(idx);
02362 #ifdef KEY
02363 }
02364 #endif
02365 if (pt->Named())
02366 Set_named(idx);
02367
02368
02369 if (!pt->Const()) {
02370 ST *sclass_st = st;
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385 switch (ST_sclass(sclass_st)) {
02386 case SCLASS_AUTO:
02387 case SCLASS_FORMAL:
02388 case SCLASS_FSTATIC:
02389 if (BE_ST_addr_used_locally(st))
02390 Set_addr_used_locally(idx);
02391 break;
02392
02393 case SCLASS_FORMAL_REF:
02394 if (BE_ST_addr_used_locally(st))
02395 Set_addr_used_locally(idx);
02396 break;
02397
02398 case SCLASS_PSTATIC:
02399 if (BE_ST_addr_used_locally(st))
02400 Set_addr_used_locally(idx);
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420 if (
02421 !ST_addr_saved(st) &&
02422 !BE_ST_addr_passed(st) &&
02423 !BE_ST_addr_used_locally(st) &&
02424 CURRENT_SYMTAB == ST_IDX_level(ST_st_idx(st)) &&
02425 aux_stab[idx].St_group() == 0 &&
02426 aux_stab[idx].Byte_size() == TY_size(ST_type(st)) &&
02427
02428 !aux_stab[idx].Is_virtual() &&
02429 !aux_stab[idx].Dmod()) {
02430 #ifndef KEY // this cause the variable to become read-only, then srdata, which
02431
02432
02433
02434 Set_ST_is_const_var(st);
02435 #endif
02436 Set_const(idx);
02437 TCON tc;
02438 if (ST_is_const_initialized(st)) {
02439 Inc_const_found();
02440 aux_stab[idx].Set_const_init();
02441 }
02442 }
02443
02444 if (ST_is_private_local(st))
02445 Set_local_static(idx);
02446 break;
02447
02448 case SCLASS_COMMON:
02449 case SCLASS_EXTERN:
02450 case SCLASS_UGLOBAL:
02451 case SCLASS_DGLOBAL:
02452 if (BE_ST_addr_used_locally(st))
02453 Set_addr_used_locally(idx);
02454
02455 if (pt->Weak()) {
02456 Set_weak_var(idx);
02457 if (has_weak_var != NULL)
02458 *has_weak_var = TRUE;
02459 }
02460
02461 #ifdef KEY
02462 if (ST_visible_outside_dso(st)) break;
02463 if (ST_is_const_var(st) && ST_is_initialized(st)) {
02464 aux_stab[idx].Set_const_init();
02465 }
02466 #endif
02467 break;
02468
02469 case SCLASS_REG:
02470
02471
02472 if (pt->Dedicated())
02473 Set_dedicated(idx);
02474 break;
02475
02476 case SCLASS_TEXT:
02477 break;
02478
02479 default:
02480 FmtAssert(FALSE, ("Handle ST class %d.", ST_sclass(st)));
02481 }
02482 }
02483 }
02484 }
02485
02486
02487
02488
02489 void
02490 OPT_STAB::Collect_ST_attr(void)
02491 {
02492 AUX_ID idx;
02493 AUX_STAB_ITER aux_stab_iter(this);
02494 INT32 n = aux_stab.Lastidx() + 1;
02495 BOOL have_weak_var = FALSE;
02496
02497 Set_addr_saved( BS_Create_Empty(n, mem_pool) );
02498 Set_addr_passed( BS_Create_Empty(n, mem_pool) );
02499 Set_addr_used_locally( BS_Create_Empty(n, mem_pool) );
02500 Set_external ( BS_Create_Empty(n, mem_pool) );
02501 Set_dedicated ( BS_Create_Empty(n, mem_pool) );
02502 Set_ref_formal( BS_Create_Empty(n, mem_pool) );
02503 Set_const ( BS_Create_Empty(n, mem_pool) );
02504 Set_named ( BS_Create_Empty(n, mem_pool) );
02505 Set_local_static( BS_Create_Empty(n, mem_pool) );
02506 if (WOPT_Enable_Unique_Pt_Vsym)
02507 Set_unique_pt ( BS_Create_Empty(n, mem_pool) );
02508 Set_virtual_var( BS_Create_Empty(n, mem_pool) );
02509 Set_weak_var( BS_Create_Empty(n, mem_pool) );
02510 Set_weak_base( BS_Create_Empty(n, mem_pool) );
02511 Set_inaccessible_to_callees( BS_Create_Empty(n, mem_pool) );
02512
02513 FOR_ALL_NODE(idx, aux_stab_iter, Init()) {
02514
02515 AUX_STAB_ENTRY *psym = Aux_stab_entry(idx);
02516 psym->Set_def_bbs(NULL);
02517 ST *st = psym->St();
02518 const INT32 stype = psym->Stype();
02519
02520 if (stype == VT_OTHER) continue;
02521
02522
02523 POINTS_TO *pt = psym->Points_to();
02524
02525 if (st != NULL) {
02526 #ifdef KEY
02527
02528
02529 TY_IDX ty = (psym->Field_id() != 0 && psym->Ty() != 0) ? psym->Ty() :
02530 (ST_class(st) == CLASS_VAR ? ST_type(st) : (TY_IDX)0);
02531 #endif
02532
02533
02534
02535
02536
02537
02538 TY_IDX hl_ty = pt->Highlevel_Ty();
02539 pt->Analyze_ST(st, psym->St_ofst(), psym->Byte_size(),
02540 psym->Bit_ofst(), psym->Bit_size(),
02541 #ifdef KEY
02542 ty,
02543 #else
02544 ST_class(st) == CLASS_VAR ? ST_type(st) : (TY_IDX)0,
02545 #endif
02546 psym->St_group() != 0 );
02547
02548
02549 if (pt->Byte_Size() == 0)
02550 pt->Set_ofst_kind(OFST_IS_UNKNOWN);
02551
02552 if (hl_ty != (TY_IDX)0 && pt->Highlevel_Ty() == (TY_IDX)0) {
02553 pt->Set_hl_ty(hl_ty);
02554 }
02555 }
02556
02557
02558 Update_attr_cache(idx, st, pt, &have_weak_var);
02559 }
02560
02561
02562
02563
02564 if (have_weak_var) {
02565 const BS *weak_set = Weak_var();
02566 for (AUX_ID idx = BS_Choose( weak_set );
02567 idx != (AUX_ID) BS_CHOOSE_FAILURE;
02568 idx = BS_Choose_Next ( weak_set, idx)) {
02569 AUX_STAB_ENTRY *psym = Aux_stab_entry(idx);
02570 ST *st = psym->St();
02571 ST *weak_base = ST_strong(st);
02572 AUX_ID weakidx;
02573 FOR_ALL_NODE(weakidx, aux_stab_iter, Init()) {
02574 AUX_STAB_ENTRY *psym = Aux_stab_entry(weakidx);
02575 if (psym->Is_real_var() && psym->St() == weak_base) {
02576 POINTS_TO *pt = psym->Points_to();
02577 Set_weak_base(weakidx);
02578 pt->Set_weak_base();
02579 pt->Reset_no_alias();
02580
02581 pt->Reset_not_addr_saved();
02582 pt->Reset_not_addr_passed();
02583
02584
02585 Update_attr_cache(weakidx, psym->St(), pt,
02586 NULL );
02587 }
02588 }
02589 }
02590 }
02591
02592
02593
02594
02595 {
02596
02597 BS *indirect = Addr_saved();
02598 indirect = BS_Union(indirect, Addr_passed(), mem_pool);
02599 indirect = BS_UnionD(indirect, Addr_used_locally(), mem_pool);
02600 indirect = BS_IntersectionD(indirect, Named());
02601 indirect = BS_DifferenceD(indirect, Const());
02602 Set_indirect(indirect);
02603 }
02604
02605
02606
02607 {
02608
02609 BS *call_by_value = BS_Union(Addr_saved(), External(), mem_pool);
02610 call_by_value = BS_UnionD(call_by_value, Addr_passed(), mem_pool);
02611 call_by_value = BS_IntersectionD(call_by_value, Named());
02612 call_by_value = BS_DifferenceD(call_by_value, Const());
02613 call_by_value = BS_UnionD(call_by_value, Dedicated(), mem_pool);
02614 Set_call_by_value(call_by_value);
02615
02616 BS *call_by_ref = BS_Union(Addr_saved(), External(), mem_pool);
02617 call_by_ref = BS_UnionD(call_by_ref, Addr_passed(), mem_pool);
02618 call_by_ref = BS_IntersectionD(call_by_ref, Named());
02619 call_by_ref = BS_DifferenceD(call_by_ref, Const());
02620 call_by_ref = BS_UnionD(call_by_ref, Dedicated(), mem_pool);
02621 Set_call_by_ref(call_by_ref);
02622 }
02623
02624
02625
02626
02627 {
02628
02629 BS *asm_alias_set = Addr_saved();
02630
02631 asm_alias_set = BS_Union(asm_alias_set, Addr_passed(), mem_pool);
02632
02633 asm_alias_set = BS_IntersectionD(asm_alias_set, Named());
02634
02635 asm_alias_set = BS_DifferenceD(asm_alias_set, Const());
02636
02637
02638
02639 asm_alias_set = BS_UnionD(asm_alias_set, Dedicated(), mem_pool);
02640 Set_asm_alias(asm_alias_set);
02641 }
02642 }
02643
02644
02645
02646
02647 void
02648 OPT_STAB::Incorporate_alias_class_info(void)
02649 {
02650 Set_inaccessible_to_callees(BS_UnionD(Alias_classification()->
02651 Inaccessible_to_callees(),
02652 Inaccessible_to_callees(),
02653 mem_pool));
02654 }
02655
02656
02657
02658
02659
02660
02661
02662 void
02663 OPT_STAB::Create(COMP_UNIT *cu, REGION_LEVEL rgn_level)
02664 {
02665 AUX_STAB_ITER aux_stab_iter(this);
02666
02667
02668 htable = cu->Htable();
02669 _cfg = cu->Cfg();
02670 pu_wn = cu->Input_tree();
02671 _rule = cu->Arule();
02672 _allow_sim_type = (cu->Phase() != MAINOPT_PHASE);
02673 _phase = cu->Phase();
02674 _rgn_level = rgn_level;
02675 #ifdef KEY
02676 _alias_mgr = cu->Alias_mgr();
02677 #endif
02678
02679 OPERATOR opr = WN_operator(pu_wn);
02680 Is_True(opr == OPR_FUNC_ENTRY || opr == OPR_REGION,
02681 ("WN is not FUNC_ENTRY or REGION entry"));
02682 if (opr == OPR_FUNC_ENTRY) {
02683 _is_varargs_func = TY_is_varargs(ST_pu_type(WN_st(pu_wn)));
02684 #ifdef KEY
02685 _is_prototyped_func = TY_has_prototype(ST_pu_type(WN_st(pu_wn)));
02686 #endif
02687 }
02688 else {
02689 _is_varargs_func = FALSE;
02690 #ifdef KEY
02691 _is_prototyped_func = TRUE;
02692 #endif
02693 }
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705 typedef ID_MAP<ST_CHAIN_INFO *, ST_IDX> STUPID_COMPILER;
02706
02707 st_chain_map = CXX_NEW(STUPID_COMPILER(256,
02708 NULL,
02709 &_st_chain_pool,
02710 FALSE),
02711 &_st_chain_pool);
02712
02713 st_chain_map->Init();
02714
02715 Collect_addr_passed_for_PU(pu_wn);
02716
02717
02718 if (WOPT_Enable_IVR) {
02719
02720 SET_OPT_PHASE("Loop normalization");
02721 BOOL trace_loop = Get_Trace (TP_WOPT2, LOOP_NORM_FLAG);
02722 if (trace_loop) {
02723 fprintf (TFile, "%sDump before Loop Normalization \n%s", DBar, DBar);
02724 fdump_tree (TFile, cu->Input_tree ());
02725 }
02726
02727 cu->Normalize_loop(cu->Input_tree());
02728
02729 if (trace_loop) {
02730 fprintf (TFile, "%sDump after Loop Normalization \n%s", DBar, DBar);
02731 fdump_tree (TFile, cu->Input_tree ());
02732 }
02733
02734 SET_OPT_PHASE("Create AUX Symbol table");
02735 }
02736
02737
02738 aux_sym_cnt = 0;
02739 Count_syms(pu_wn);
02740
02741
02742 Set_BE_ST_pu_has_valid_addr_flags(Get_Current_PU_ST());
02743
02744
02745 aux_stab.Alloc_array(unsigned(aux_sym_cnt*1.2)+10);
02746 aux_stab.Setidx(aux_sym_cnt);
02747 aux_stab.Bzero_array();
02748
02749
02750 Convert_ST_to_AUX(pu_wn, NULL);
02751
02752 Collect_nested_ref_info();
02753
02754
02755 Init_last_preg(Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB)));
02756
02757
02758 Make_st_group();
02759 #if 0 // OPT_REVISE_SSA will use Enter_symbol later
02760
02761 CXX_DELETE(st_chain_map, &_st_chain_pool);
02762 st_chain_map = NULL;
02763 #endif
02764
02765
02766 Canonicalize();
02767
02768
02769 AUX_ID return_vsym = Create_vsym(EXPR_IS_ADDR);
02770 Set_return_vsym(return_vsym);
02771 POINTS_TO *pt = Aux_stab_entry(return_vsym)->Points_to();
02772 pt->Init();
02773 pt->Set_expr_kind(EXPR_IS_ADDR);
02774 pt->Set_base_kind(BASE_IS_UNKNOWN);
02775 pt->Set_ofst_kind(OFST_IS_UNKNOWN);
02776 pt->Set_base(NULL);
02777 pt->Set_global();
02778
02779
02780 Collect_ST_attr();
02781
02782
02783
02784 _ver_stab = CXX_NEW(VER_STAB_ARRAY_TYPE(&_ver_pool), &_ver_pool);
02785
02786
02787 UINT dummy;
02788 _ver_stab->New_entry(dummy);
02789 _ver_stab->New_entry(dummy);
02790 Is_True(_ver_stab->Size() == 2, ("New_entry of ver_stab failed."));
02791 }
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803 AUX_ID
02804 OPT_STAB::Find_vsym_with_base(ST *st)
02805 {
02806 AUX_ID i;
02807 AUX_STAB_ITER aux_stab_iter(this);
02808 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02809 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02810 if (vsym->Points_to()->Based_sym() == st)
02811 return i;
02812 }
02813 return (AUX_ID) 0;
02814 }
02815
02816
02817 void
02818 OPT_STAB::Init_mp_attribute(void)
02819 {
02820 AUX_ID i;
02821 AUX_STAB_ITER aux_stab_iter(this);
02822 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02823 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02824 vsym->Set_mp_shared();
02825 vsym->Reset_mp_lastlocal();
02826 vsym->Reset_mp_reduction();
02827 vsym->Reset_mp_firstprivate();
02828 }
02829 }
02830
02831
02832 AUX_ID
02833 OPT_STAB::Find_vsym_with_base_ofst_and_size(ST *base,
02834 INT64 byte_ofst, INT64 byte_size,
02835 UINT8 bit_ofst, UINT8 bit_size)
02836 {
02837 AUX_ID i;
02838 AUX_STAB_ITER aux_stab_iter(this);
02839 AUX_ID best_vsym = 0;
02840
02841 if (byte_size > 0) {
02842
02843
02844 UINT64 best_bit_size = UINT64_MAX;
02845 UINT8 best_bit_ofst = 0;
02846 UINT64 target_bit_size;
02847 UINT8 target_bit_ofst;
02848
02849 if (bit_size == 0) {
02850
02851 target_bit_size = byte_size * 8;
02852 target_bit_ofst = 0;
02853 } else {
02854 target_bit_size = bit_size;
02855 target_bit_ofst = bit_ofst;
02856 }
02857
02858 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02859 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02860 if ((vsym->Is_real_var() || vsym->Stype() == VT_LDA_VSYM) &&
02861 vsym->Base() == base &&
02862 vsym->Base_byte_ofst() == byte_ofst) {
02863
02864 if (vsym->Bit_size() == 0) {
02865
02866 UINT64 vsym_size = vsym->Byte_size() * 8;
02867 if (target_bit_ofst == 0 && vsym_size == target_bit_size) {
02868 best_vsym = i;
02869 goto found_scalar_vsym;
02870 } else if (best_bit_ofst == 0 &&
02871 vsym_size < best_bit_size &&
02872 vsym_size >= target_bit_size) {
02873 best_vsym = i;
02874 best_bit_size = vsym_size;
02875 }
02876 } else {
02877
02878 if (vsym->Bit_ofst() == target_bit_ofst &&
02879 vsym->Bit_size() == target_bit_size) {
02880 best_vsym = i;
02881 goto found_scalar_vsym;
02882 } else if (vsym->Bit_ofst() <= target_bit_ofst &&
02883 (vsym->Bit_ofst() + vsym->Bit_size()) >=
02884 (target_bit_ofst + target_bit_size)) {
02885 if (vsym->Bit_ofst() >= best_bit_ofst &&
02886 (vsym->Bit_ofst() + vsym->Bit_size()) <
02887 (best_bit_ofst + best_bit_size)) {
02888 best_vsym = i;
02889 best_bit_size = vsym->Bit_size();
02890 best_bit_ofst = vsym->Bit_ofst();
02891 }
02892 }
02893 }
02894 }
02895 }
02896 found_scalar_vsym:
02897 if (best_vsym != 0) {
02898 INT32 stype = Aux_stab_entry(best_vsym)->Stype();
02899 if (stype == VT_NO_LDA_SCALAR ||
02900 (stype == VT_LDA_VSYM &&
02901 Aux_stab_entry(best_vsym)->Byte_size() == byte_size &&
02902 Aux_stab_entry(best_vsym)->Bit_size() == bit_size)) {
02903 Aux_stab_entry(best_vsym)->Set_stype(VT_LDA_SCALAR);
02904 }
02905 return best_vsym;
02906 }
02907
02908
02909
02910
02911 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02912 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02913 if ((vsym->Stype() == VT_LDA_VSYM || vsym->Stype() == VT_LDA_SCALAR) &&
02914 vsym->Base() == base &&
02915 vsym->Base_byte_ofst() <= byte_ofst &&
02916 vsym->Base_byte_ofst() + vsym->Byte_size() >= byte_ofst + byte_size)
02917 return i;
02918 }
02919 }
02920
02921
02922
02923
02924 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02925 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02926 if (vsym->Stype() == VT_LDA_VSYM &&
02927 vsym->Base() == base &&
02928 vsym->Base_byte_ofst() == byte_ofst &&
02929 vsym->Byte_size() == 0)
02930 return i;
02931 }
02932 return 0;
02933 }
02934
02935
02936 AUX_ID
02937 #ifdef KEY
02938 OPT_STAB::Find_vsym_with_st(ST *st, BOOL indirect, POINTS_TO * pt)
02939 #else
02940 OPT_STAB::Find_vsym_with_st(ST *st)
02941 #endif
02942 {
02943 AUX_ID i;
02944 AUX_STAB_ITER aux_stab_iter(this);
02945 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02946 AUX_STAB_ENTRY *vsym = Aux_stab_entry(i);
02947 #ifdef KEY
02948 if (vsym->Is_virtual() && vsym->St() == st &&
02949 (vsym->Indirect_access()!=0) == indirect &&
02950 (!WOPT_Enable_New_Vsym_Allocation || !pt ||
02951 Rule()->Aliased_Memop(vsym->Points_to(), pt)))
02952 #else
02953 if (vsym->Is_virtual() && vsym->St() == st)
02954 #endif
02955 return i;
02956 }
02957 return (AUX_ID) 0;
02958 }
02959
02960
02961 AUX_ID
02962 OPT_STAB::Find_sym_with_st_and_ofst(ST *st, INT64 ofst)
02963 {
02964 AUX_ID i;
02965 AUX_STAB_ITER aux_stab_iter(this);
02966 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
02967 AUX_STAB_ENTRY *sym = Aux_stab_entry(i);
02968 if (sym->St() == st && sym->St_ofst() == ofst)
02969 return i;
02970 }
02971 return (AUX_ID) 0;
02972 }
02973
02974 #ifdef KEY // taken from wn_mp.cxx
02975 static const char * const dope_str_prefix = ".dope." ;
02976 static const INT dope_str_prefix_len = 6;
02977
02978 BOOL
02979 ST_Has_Dope_Vector(ST *st) {
02980 if (ST_class(st) != CLASS_VAR)
02981 return FALSE;
02982
02983 if ( TY_is_f90_pointer(ST_type(st)) )
02984 return TRUE;
02985
02986 TY_IDX ty = ST_type(st);
02987 while (TY_kind(ty) == KIND_POINTER)
02988 ty = TY_pointed(ty);
02989
02990 if (TY_kind(ty) == KIND_STRUCT &&
02991 strncmp(TY_name(ty), dope_str_prefix, dope_str_prefix_len) == 0)
02992 return TRUE;
02993
02994 return FALSE;
02995 }
02996 #endif
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010 AUX_ID
03011 OPT_STAB::Identify_vsym(WN *memop_wn)
03012 {
03013 POINTS_TO scratch_pt;
03014 scratch_pt.Init();
03015 if (Update_From_Restricted_Map(memop_wn, &scratch_pt)) {
03016
03017
03018 Is_True(scratch_pt.Based_sym() != NULL,
03019 ("Based symbol must be set for restricted map entry"));
03020
03021
03022 if (scratch_pt.Unique_pt() ||
03023 scratch_pt.Restricted()) {
03024 AUX_ID var = Find_vsym_with_base(scratch_pt.Based_sym());
03025 if (var == 0) {
03026 var = Create_vsym(EXPR_IS_ANY);
03027 AUX_STAB_ENTRY *vsym = Aux_stab_entry(var);
03028 vsym->Points_to()->Copy_fully(scratch_pt);
03029 vsym->Set_stype(VT_UNIQUE_VSYM);
03030 }
03031 else {
03032 Is_True(Aux_stab_entry(var)->Stype() == VT_UNIQUE_VSYM ||
03033 Aux_stab_entry(var)->Stype() == VT_SPECIAL_VSYM,
03034 ("vsym based on unique/restrict pointer must be unique "
03035 "or special"));
03036 }
03037 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG)) {
03038 fprintf(TFile, "Identify_vsym: Returning aux_id %u as unique "
03039 "based on\n", var);
03040 Print_ST(TFile, Aux_stab_entry(var)->Points_to()->Based_sym(), TRUE);
03041 }
03042 return var;
03043 }
03044 }
03045 OPERATOR opr = WN_operator(memop_wn);
03046 WN *addr_wn = ((OPERATOR_is_scalar_istore (opr) ||
03047 opr == OPR_MSTORE) ? WN_kid1(memop_wn) : WN_kid0(memop_wn));
03048 INT64 offset = (opr == OPR_PARM || opr == OPR_ASM_INPUT ? (INT64) 0
03049 : WN_offset(memop_wn));
03050
03051
03052 BOOL direct_use = ((addr_wn != NULL) &&
03053 (WN_operator(addr_wn) == OPR_LDID) &&
03054 (offset == 0));
03055
03056 addr_wn = Find_addr_recur(addr_wn, *this);
03057
03058 if (addr_wn != NULL) {
03059 switch (WN_operator(addr_wn)) {
03060 case OPR_LDA:
03061 AUX_ID var;
03062 var = WN_aux(addr_wn);
03063 Is_True(var != 0, ("lda not entered into aux_stab."));
03064 return var;
03065 case OPR_LDID:
03066 {
03067 ST *st = aux_stab[WN_aux(addr_wn)].St();
03068 AUX_ID vsym_id;
03069
03070 if (ST_sclass(st) == SCLASS_FORMAL&&
03071 IS_FORTRAN &&
03072 Alias_Pointer_Parms &&
03073 ! ST_is_value_parm(st)) {
03074 vsym_id = Find_vsym_with_base(st);
03075 if (vsym_id == 0) {
03076 vsym_id = Create_vsym(EXPR_IS_ANY);
03077 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03078 vsym->Points_to()->Set_based_sym(st);
03079 if (direct_use) {
03080 vsym->Set_stype(VT_UNIQUE_VSYM);
03081 }
03082 }
03083 else {
03084 if (! direct_use) {
03085 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03086 vsym->Set_stype(VT_SPECIAL_VSYM);
03087 }
03088 }
03089 return vsym_id;
03090 }
03091 if (WOPT_Enable_Unique_Pt_Vsym &&
03092 ST_class(st) == CLASS_VAR &&
03093 (ST_pt_to_unique_mem(st) ||
03094 #ifdef KEY
03095
03096
03097 #endif
03098 TY_is_restrict(ST_type(st)))) {
03099 vsym_id = Find_vsym_with_base(st);
03100 #ifdef KEY // workaround f90 front-end not setting ST_pt_to_unique_mem flag
03101
03102
03103
03104 #endif
03105 if (vsym_id == 0) {
03106 vsym_id = Create_vsym(EXPR_IS_ANY);
03107 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03108 if (ST_pt_to_unique_mem(st)) {
03109 vsym->Points_to()->Set_unique_pt();
03110 }
03111 if (TY_is_restrict(ST_type(st))) {
03112 vsym->Points_to()->Set_restricted();
03113 }
03114 vsym->Points_to()->Set_based_sym(st);
03115 if (direct_use) {
03116 vsym->Set_stype(VT_UNIQUE_VSYM);
03117 }
03118 }
03119 else {
03120 if (! direct_use) {
03121 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03122 vsym->Set_stype(VT_SPECIAL_VSYM);
03123 }
03124 }
03125 return vsym_id;
03126 }
03127 #ifdef KEY
03128
03129 if (WOPT_Enable_Vsym_Unique && !ST_Has_Dope_Vector(st)) {
03130 vsym_id = Find_vsym_with_st(st, !direct_use);
03131 if (vsym_id == 0) {
03132 vsym_id = Create_vsym(EXPR_IS_ANY);
03133 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03134 vsym->Points_to()->Set_based_sym(NULL);
03135 vsym->Set_st(st);
03136 if (direct_use) {
03137 vsym->Set_stype(VT_UNIQUE_VSYM);
03138 }
03139 else {
03140 Is_True (vsym->Special_vsym(),
03141 ("Identify_vsym: Expected VT_SPECIAL_VSYM"));
03142 vsym->Set_indirect_access();
03143 }
03144 }
03145 else {
03146
03147 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03148
03149 FmtAssert (direct_use == !vsym->Indirect_access(),
03150 ("Identify_vsym: incompatible access flag in vsym"));
03151 if (!direct_use)
03152
03153 FmtAssert (vsym->Special_vsym(),
03154 ("Identify_vsym: Expected VT_SPECIAL_VSYM"));
03155
03156
03157 }
03158 return vsym_id;
03159 }
03160 #else
03161 if (WOPT_Enable_Vsym_Unique) {
03162 vsym_id = Find_vsym_with_st(st);
03163 if (vsym_id == 0) {
03164 vsym_id = Create_vsym(EXPR_IS_ANY);
03165 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03166 vsym->Points_to()->Set_based_sym(NULL);
03167 vsym->Set_st(st);
03168 if (direct_use) {
03169 vsym->Set_stype(VT_UNIQUE_VSYM);
03170 }
03171 }
03172 else {
03173 if (! direct_use) {
03174 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03175 vsym->Set_stype(VT_SPECIAL_VSYM);
03176 }
03177 }
03178 return vsym_id;
03179 }
03180 #endif
03181 }
03182 default:
03183 addr_wn = NULL;
03184 }
03185 }
03186
03187 if ((OPERATOR_is_load (opr) || OPERATOR_is_store (opr)) &&
03188 WOPT_Enable_Vsym_Unique) {
03189 IDTYPE ac = _alias_classification->Alias_class(memop_wn);
03190 if (ac != OPTIMISTIC_AC_ID && ac != PESSIMISTIC_AC_ID) {
03191 AUX_ID vsym_id = _ac_2_vsym_map.Lookup(ac);
03192 if (vsym_id == (AUX_ID)0) {
03193 vsym_id = Create_vsym(EXPR_IS_ANY);
03194 AUX_STAB_ENTRY *vsym = Aux_stab_entry(vsym_id);
03195 vsym->Set_stype(VT_UNIQUE_VSYM);
03196 vsym->Points_to()->Set_alias_class (ac);
03197 _ac_2_vsym_map.Insert(ac, vsym_id);
03198 }
03199 return vsym_id;
03200 }
03201 }
03202
03203
03204 if (Default_vsym() == 0) {
03205
03206 Set_default_vsym(Create_vsym(EXPR_IS_ANY));
03207
03208 Aux_stab_entry(Default_vsym())->Points_to()->Set_default_vsym();
03209 }
03210 return Default_vsym();
03211 }
03212
03213
03214
03215
03216
03217
03218
03219 void
03220 OPT_STAB::Clear_coderep(void)
03221 {
03222 for (INT32 i = 0; i <= aux_stab.Lastidx(); i++)
03223 aux_stab[i].Clear_coderep();
03224 }
03225
03226
03227
03228 void
03229 OPT_STAB::Reset_def_bbs(void)
03230 {
03231 for (INT32 i = 0; i <= aux_stab.Lastidx(); i++)
03232 aux_stab[i].Set_def_bbs(NULL);
03233 }
03234
03235
03236
03237 void
03238 OPT_STAB::New_coderep(MEM_POOL *pool)
03239 {
03240 for (INT32 i = 0; i <= aux_stab.Lastidx(); i++)
03241 aux_stab[i].Set_coderep(CXX_NEW(STACK<CODEREP*>(pool), pool));
03242 }
03243
03244
03245
03246 void
03247 OPT_STAB::New_stack(MEM_POOL *pool)
03248 {
03249 for (INT32 i = 0; i <= aux_stab.Lastidx(); i++)
03250 aux_stab[i].Set_stack(CXX_NEW(STACK<AUX_ID>(pool), pool));
03251 }
03252
03253
03254
03255
03256 void
03257 OPT_STAB::Check_stack(void)
03258 {
03259 for (INT32 i = 0; i <= aux_stab.Lastidx(); i++)
03260 Is_True(Stack_elements(i) <= 1, ("Non empty stack in aux_stab"));
03261 }
03262
03263
03264
03265
03266
03267 VER_ID
03268 OPT_STAB::Gen_name(AUX_ID var)
03269 {
03270 UINT32 i = Version(var);
03271 VER_ID du;
03272 _ver_stab->New_entry(du);
03273 Ver_stab_entry(du)->Init(var, i+1, NULL, NULL, NO_STMT);
03274 Set_version(var, i+1);
03275 Stack(var)->Push(du);
03276 return du;
03277 }
03278
03279
03280
03281
03282
03283 VER_ID
03284 OPT_STAB::Gen_name_phi(PHI_NODE *phi)
03285 {
03286 VER_ID du;
03287 du = Gen_name(phi->Aux_id());
03288 phi->Set_result(du);
03289 return du;
03290 }
03291
03292
03293
03294
03295 VER_ID
03296 OPT_STAB::Gen_name_chi(CHI_NODE *chi, WN *wn)
03297 {
03298 VER_ID du;
03299 du = Gen_name(chi->Aux_id());
03300 Ver_stab_entry(du)->Set_chi_wn(wn);
03301 chi->Set_result(du);
03302 return du;
03303 }
03304
03305
03306
03307
03308
03309 VER_ID
03310 OPT_STAB::Get_name(AUX_ID var)
03311 {
03312 VER_ID du;
03313 du = Stack(var)->Top();
03314 return du;
03315 }
03316
03317
03318
03319
03320 POINTS_TO_LIST *
03321 OPT_STAB::Black_box_refs(const WN *wn) const
03322 {
03323 return (POINTS_TO_LIST *) WN_MAP_Get(WN_box_refs(), wn);
03324 }
03325
03326
03327 POINTS_TO_LIST *
03328 OPT_STAB::Black_box_defs(const WN *wn) const
03329 {
03330 return (POINTS_TO_LIST *) WN_MAP_Get(WN_box_defs(), wn);
03331 }
03332
03333
03334 void
03335 OPT_STAB::Add_black_box_ref( WN *wn, POINTS_TO *ref ) const
03336 {
03337 POINTS_TO_LIST *ptl = Black_box_refs(wn);
03338
03339 if ( ptl == NULL ) {
03340 ptl = CXX_NEW(POINTS_TO_LIST,mem_pool);
03341 WN_MAP_Set( WN_box_refs(), wn, (void *)ptl );
03342 }
03343
03344 ptl->Prepend( ref, mem_pool );
03345 }
03346
03347
03348 void
03349 OPT_STAB::Add_black_box_def( WN *wn, POINTS_TO *def ) const
03350 {
03351 POINTS_TO_LIST *ptl = Black_box_defs(wn);
03352
03353 if ( ptl == NULL ) {
03354 ptl = CXX_NEW(POINTS_TO_LIST,mem_pool);
03355 WN_MAP_Set( WN_box_defs(), wn, (void *)ptl );
03356 }
03357
03358 ptl->Prepend( def, mem_pool );
03359 }
03360
03361
03362
03363
03364 MU_NODE *
03365 MU_LIST::Search_mu_node( AUX_ID var )
03366 {
03367 MU_LIST_ITER mu_iter;
03368 MU_NODE *munode;
03369 FOR_ALL_NODE(munode, mu_iter, Init(this))
03370 if ( munode->Aux_id() == var )
03371 return munode;
03372 return NULL;
03373 }
03374
03375
03376
03377
03378 CHI_NODE *
03379 CHI_LIST::Search_chi_node( AUX_ID var )
03380 {
03381 CHI_LIST_ITER chi_iter;
03382 CHI_NODE *chinode;
03383 FOR_ALL_NODE(chinode, chi_iter, Init(this))
03384 if ( chinode->Aux_id() == var )
03385 return chinode;
03386 return NULL;
03387 }
03388
03389
03390
03391 void
03392 MU_NODE::Set_OPND(CODEREP *cr, BOOL set_dont_prop)
03393 {
03394 _u._cr = cr;
03395 if (cr && set_dont_prop)
03396 cr->Set_flag(CF_DONT_PROP);
03397 }
03398
03399
03400
03401 void
03402 CHI_NODE::Set_OPND(CODEREP *cr, BOOL set_dont_prop)
03403 {
03404 _opnd._cr = cr;
03405 if (cr && set_dont_prop)
03406 cr->Set_flag(CF_DONT_PROP);
03407 }
03408
03409
03410
03411
03412
03413 void
03414 OPT_STAB::Remap_ver_synonym(WN *wn)
03415 {
03416 INT32 i;
03417
03418 if (wn == NULL) return;
03419
03420 const OPERATOR opr = WN_operator(wn);
03421
03422 Is_True(!OPERATOR_is_scf(opr) || opr == OPR_REGION, ("Wn is SCF"));
03423
03424 if (WN_has_ver(wn)) {
03425 VER_ID idx = WN_ver(wn);
03426 if (Ver_stab_entry(idx)->Synonym()) {
03427 VER_ID s = idx;
03428 while (s != 0 && Ver_stab_entry(s)->Synonym())
03429 s = Ver_stab_entry(s)->Synonym();
03430 WN_set_ver(wn, s);
03431 if (Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG))
03432 fprintf(TFile, "remap verid %d to %d\n", idx, s);
03433 }
03434 }
03435
03436 if ( WN_has_mu(wn, Cfg()->Rgn_level()) ) {
03437 OCC_TAB_ENTRY *occ = Get_occ(wn);
03438 if (occ->Is_stmt()) {
03439 MU_LIST_ITER mu_iter;
03440 MU_NODE *mnode;
03441 MU_LIST *mu_list = Get_stmt_mu_list(wn);
03442 FOR_ALL_NODE( mnode, mu_iter, Init( mu_list)) {
03443 VER_ID idx = mnode->Opnd();
03444 if (Ver_stab_entry(idx)->Synonym()) {
03445 VER_ID s = idx;
03446 while (s != 0 && Ver_stab_entry(s)->Synonym())
03447 s = Ver_stab_entry(s)->Synonym();
03448 mnode->Set_opnd(s);
03449 }
03450 }
03451 } else {
03452 MU_NODE *mnode = Get_mem_mu_node(wn);
03453 VER_ID idx = mnode->Opnd();
03454 if (Ver_stab_entry(idx)->Synonym()) {
03455 VER_ID s = idx;
03456 while (s != 0 && Ver_stab_entry(s)->Synonym())
03457 s = Ver_stab_entry(s)->Synonym();
03458 mnode->Set_opnd(s);
03459 }
03460 }
03461 }
03462
03463 if ( WN_has_chi(wn, Cfg()->Rgn_level()) ) {
03464 CHI_LIST_ITER chi_iter;
03465 CHI_NODE *cnode;
03466 CHI_LIST *chi_list = Get_generic_chi_list(wn);
03467 FOR_ALL_NODE( cnode, chi_iter, Init(chi_list)) {
03468 VER_ID idx = cnode->Opnd();
03469 if (Ver_stab_entry(idx)->Synonym()) {
03470 VER_ID s = idx;
03471 while (s != 0 && Ver_stab_entry(s)->Synonym())
03472 s = Ver_stab_entry(s)->Synonym();
03473 cnode->Set_opnd(s);
03474 }
03475 }
03476 }
03477
03478 if (opr == OPR_REGION) {
03479 RID *rid = REGION_get_rid(wn);
03480 Is_True(rid != NULL,("OPT_STAB::Remap_aux_synonym, NULL rid"));
03481 if (RID_level(rid) >= Rgn_level())
03482 return;
03483 }
03484
03485 if ( opr == OPR_COMPGOTO ) {
03486
03487 Remap_ver_synonym(WN_kid(wn,0));
03488 }
03489
03490 else if (!OPERATOR_is_black_box(opr) && opr != OPR_EXC_SCOPE_BEGIN) {
03491 if (opr == OPR_ASM_STMT) {
03492 i = 2;
03493 }
03494 else {
03495 i = 0;
03496 }
03497 for (; i < WN_kid_count(wn); i++) {
03498 Remap_ver_synonym(WN_kid(wn,i));
03499 }
03500 }
03501 }
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511 void
03512 OPT_STAB::Clear_itab_bitpos( void )
03513 {
03514 AUX_ID var;
03515 AUX_STAB_ITER aux_stab_iter(this);
03516
03517 FOR_ALL_NODE(var, aux_stab_iter, Init()) {
03518 Set_itab_bitpos( var, ILLEGAL_BP );
03519 }
03520 }
03521
03522
03523
03524
03525
03526 void
03527 OPT_STAB::Rename_aux_id_list_to_bitpos( void )
03528 {
03529 AUX_ID var;
03530 AUX_STAB_ITER aux_stab_iter(this);
03531
03532 FOR_ALL_NODE(var, aux_stab_iter, Init()) {
03533 AUX_STAB_ENTRY *vsym = Aux_stab_entry( var );
03534 if ( vsym->Is_virtual() ) {
03535 AUX_ID_LIST_ITER id_list_iter;
03536 AUX_ID_NODE *id_node;
03537 FOR_ALL_ELEM( id_node, id_list_iter, Init(vsym->Aux_id_list()) ) {
03538 AUX_STAB_ENTRY *id_entry = Aux_stab_entry(id_node->Aux_id());
03539 id_node->Set_aux_id( (AUX_ID) id_entry->Itab_bitpos() );
03540 }
03541 }
03542 }
03543 }
03544
03545
03546
03547
03548 void
03549 OPT_STAB::Convert_EH_pragmas(WN *wn)
03550 {
03551 Is_True(REGION_is_EH(wn), ("OPT_STAB::Convert_EH_pragmas, wrong kind"));
03552 WN *stmt, *pragmas = WN_region_pragmas(wn);
03553 STMT_ITER stmt_iter;
03554 FOR_ALL_ELEM(stmt, stmt_iter, Init(WN_first(pragmas), WN_last(pragmas))) {
03555 if (WN_operator(stmt) == OPR_CALL) {
03556 for (INT i=0; i<WN_kid_count(stmt); i++) {
03557 WN *kid = WN_kid0(WN_kid(stmt,i));
03558 if (WN_has_aux(kid)) {
03559 AUX_ID aux_id = WN_aux(kid);
03560 WN_st_idx(kid) = ST_st_idx(St(aux_id));
03561 WN_offset(kid) = St_ofst(aux_id);
03562 }
03563 }
03564 return;
03565 }
03566 }
03567 }
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579 void
03580 CHI_NODE::Print(FILE *fp) const
03581 {
03582 #ifdef KEY
03583 fprintf(fp, "sym%dv%d <- chi( sym%dv%d ) %s\n", Aux_id(), Result(), Aux_id(), Opnd(), Live() ? "LIVE" : "NOT LIVE");
03584 #else
03585 fprintf(fp, "sym%d <- chi( sym%d ) %s\n", Result(), Opnd(),
03586 Live() ? "LIVE" : "NOT LIVE");
03587 #endif
03588 }
03589
03590
03591 void
03592 CHI_LIST::Print(FILE *fp)
03593 {
03594 CHI_LIST_ITER chi_iter;
03595 CHI_NODE *cnode;
03596
03597 FOR_ALL_NODE(cnode, chi_iter, Init(this)) {
03598 cnode->Print(fp);
03599 }
03600 }
03601
03602
03603
03604
03605 void
03606 MU_NODE::Print(FILE *fp) const
03607 {
03608 #ifdef KEY
03609 fprintf(fp, " sym%dv%d ", Aux_id(), Opnd());
03610 #else
03611 fprintf(fp, " sym%d ", Aux_id());
03612 #endif
03613 }
03614
03615
03616 void
03617 MU_LIST::Print(FILE *fp)
03618 {
03619 MU_LIST_ITER mu_iter;
03620 MU_NODE *mnode;
03621
03622 fprintf(fp, " mu[");
03623 FOR_ALL_NODE(mnode, mu_iter, Init(this)) {
03624 mnode->Print(fp);
03625 }
03626 fprintf(fp, "]\n");
03627 }
03628
03629
03630
03631
03632 void OPT_STAB::Print_aux_entry(AUX_ID i, FILE *fp)
03633 {
03634 BB_LIST *bbl;
03635 AUX_STAB_ENTRY *psym = &aux_stab[i];
03636
03637 bbl = psym->Def_bbs();
03638 fprintf(fp, " [%3d] ", i);
03639 if (i == Return_vsym()) fprintf(fp,"Return_vsym ");
03640 if (i == Default_vsym()) fprintf(fp,"Default_vsym ");
03641 switch (psym->Stype()) {
03642 case VT_NO_LDA_SCALAR:
03643 case VT_LDA_SCALAR:
03644 case VT_LDA_VSYM:
03645 case VT_UNIQUE_VSYM:
03646 case VT_SPECIAL_VSYM:
03647
03648 if (aux_stab[i].St() != NULL) {
03649 fprintf(fp, "VAR st=%s base=%s byte ofst=%lld byte size=%lld"
03650 " bit ofst=%d bit size=%d sclass=%d mclass=%d\n",
03651 aux_stab[i].St_name(), aux_stab[i].Base_name(),
03652 aux_stab[i].Base_byte_ofst(), aux_stab[i].Byte_size(),
03653 aux_stab[i].Bit_ofst(), aux_stab[i].Bit_size(),
03654 ST_sclass(aux_stab[i].St()), aux_stab[i].Mclass());
03655 } else
03656 fprintf(fp, "VAR st=null\n");
03657
03658 if (psym->Is_real_var())
03659 fprintf(fp, " is_real");
03660 if (psym->Is_virtual())
03661 fprintf(fp, " is_virtual");
03662 if (psym->Loop_index())
03663 fprintf(fp, " loop-index");
03664 if (psym->Has_nested_ref())
03665 fprintf(fp, " nested-ref");
03666 if (psym->Is_volatile())
03667 fprintf(fp, " volatile");
03668 if (psym->Disable_local_rvi())
03669 fprintf(fp, " disable-local-rvi");
03670 if (psym->Lr_shrink_cand())
03671 fprintf(fp, " lr-shrink-cand");
03672 fprintf(fp, "\n");
03673 if (Addr_saved(i) || Addr_passed(i) || External(i)
03674 || Ref_formal(i) || Unique_vsym(i)) {
03675 fprintf(fp, " attr=");
03676 if (Addr_saved(i)) fprintf(fp, "addr_saved ");
03677 if (Addr_passed(i)) fprintf(fp, "addr_passed ");
03678 if (External(i)) fprintf(fp, "extern ");
03679 if (Ref_formal(i)) fprintf(fp, "ref_formal ");
03680 if (Unique_vsym(i)) fprintf(fp, "unique_vsym ");
03681 fprintf(fp, "\n");
03682 }
03683 break;
03684
03685 case VT_OTHER:
03686 fprintf(fp, "SYMBL st=%s base=%s ofst=%lld\n",
03687 aux_stab[i].St_name(), aux_stab[i].Base_name(),
03688 aux_stab[i].Base_byte_ofst());
03689 break;
03690
03691 default:
03692 fprintf(fp, "UNKNOWN TYPE\n" );
03693 break;
03694 }
03695 if (psym->Is_real_var() || psym->Is_virtual()) {
03696 if (bbl->Len() > 0) {
03697 fprintf(fp, " defined in BBs ");
03698 bbl->Print(fp);
03699 fprintf(fp, "\n");
03700 }
03701 }
03702 if (psym->Is_real_var()) {
03703 if (aux_stab[i].St_chain()) {
03704 fprintf(fp, " st_chain ");
03705 VER_ID cur = i;
03706 while (cur) {
03707 fprintf(fp, " %d", cur);
03708 cur = aux_stab[cur].St_chain();
03709 }
03710 fprintf(fp, "\n");
03711 }
03712 if (aux_stab[i].St_group()) {
03713 fprintf(fp, " st_group ");
03714 VER_ID cur = i;
03715 do {
03716 fprintf(fp, " %d", cur);
03717 cur = aux_stab[cur].St_group();
03718 } while (cur && cur != i);
03719 fprintf(fp, "\n");
03720 }
03721 }
03722 }
03723
03724
03725
03726
03727 #ifdef KEY
03728 void OPT_STAB::Print(FILE *fp, WN *entry_wn)
03729 #endif
03730 {
03731 AUX_ID i;
03732 AUX_STAB_ITER aux_stab_iter(this);
03733
03734 fprintf( TFile, "%sAux symbol table\n%s", DBar, DBar );
03735
03736 fprintf(fp, "aux_stab.Lastidx()=%d\n", aux_stab.Lastidx());
03737 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
03738 Print_aux_entry(i, fp);
03739 }
03740
03741 fprintf( TFile, "%sOcc table\n%s", DBar, DBar );
03742 #ifdef KEY
03743 if (entry_wn)
03744 Print_occ_tab(fp,WN_func_body(entry_wn));
03745 #endif
03746
03747 }
03748
03749
03750 BOOL
03751 AUX_STAB_ENTRY::Has_multiple_signs(void) const
03752 {
03753 CODEREP *cr;
03754 CODEREP_ITER iter;
03755
03756 if (Cr_list()) {
03757 BOOL sign_extd;
03758 FOR_ALL_NODE(cr, iter, Init(Cr_list())) {
03759 if (!cr->Is_flag_set(CF_MADEUP_TYPE))
03760 sign_extd = cr->Is_sign_extd();
03761 }
03762
03763 FOR_ALL_NODE(cr, iter, Init(Cr_list())) {
03764 if (( !cr->Is_flag_set(CF_MADEUP_TYPE) &&
03765 cr->Is_sign_extd() != sign_extd )
03766 ||
03767 ( cr->Is_flag_set(CF_DEF_BY_CHI) &&
03768 (cr->Defstmt()->Op() == OPC_OPT_CHI ||
03769 cr->Defstmt()->Op()==OPC_REGION )) )
03770 return TRUE;
03771 }
03772 }
03773 return FALSE;
03774
03775 }
03776
03777 #ifdef KEY
03778 void OPT_STAB::Print_occ_tab(FILE *fp, WN *wn)
03779 #endif
03780 {
03781 #if 1
03782
03783
03784
03785
03786
03787
03788 #ifdef KEY
03789 if (wn==NULL)
03790 return;
03791 OPERATOR opr = WN_operator( wn );
03792 if (opr == OPR_BLOCK) {
03793 for (WN *wn2 = WN_first(wn); wn2 != NULL; wn2 = WN_next (wn2) )
03794 Print_occ_tab(fp, wn2);
03795 } else {
03796 OCC_TAB_ENTRY *occ = Get_occ(wn);
03797 if (occ)
03798 occ->Print(fp);
03799 for ( INT32 i = 0; i < WN_kid_count( wn ); i++ )
03800 Print_occ_tab( fp, WN_kid( wn, i ));
03801 }
03802 #endif
03803 #else
03804
03805 WN_MAP_ITER map_iter;
03806 INT32 category;
03807 OCC_TAB_ENTRY **addr;
03808 for (category = 0; category < WN_MAP_CATEGORIES; category++) {
03809 WN_MAP_ITER_Init(&map_iter, Current_Map_Tab, WN_sym_map(),
03810 (OPCODE_MAPCAT) category);
03811 while (addr = (OCC_TAB_ENTRY **) WN_MAP_ITER_Step(&map_iter, NULL)) {
03812 if (*addr != NULL)
03813 (*addr)->Print(fp);
03814 }
03815 }
03816 #endif
03817 }
03818
03819
03820 void
03821 OPT_STAB::Print_top_nth_coderep(AUX_ID i, INT32 n, FILE *fp)
03822 {
03823 Top_nth_coderep(i, n)->Print(0, fp);
03824 }
03825
03826
03827
03828
03829
03830
03831
03832 static void
03833 VER_STAB_FLAG_Print( INT flag, BOOL verbose, FILE *fp=stderr )
03834 {
03835 fprintf( fp, " flag:%02x ", flag );
03836 if ( verbose ) {
03837 if ( flag & VS_ANY_USE )
03838 fprintf( fp, " any_use " );
03839 if ( flag & VS_REAL_USE )
03840 fprintf( fp, " real_use " );
03841 }
03842 }
03843
03844
03845
03846
03847 void VER_STAB_ENTRY::Print(FILE *fp, VER_ID ver_id) const
03848 {
03849 fprintf(fp, " vers %d: sym=%3d ver=%3d ", ver_id, Aux_id(), Version());
03850 VER_STAB_FLAG_Print( flags, FALSE, fp );
03851
03852 switch (Type()) {
03853 case WHIRL_STMT:
03854 fprintf(fp, "Wn *0x%p ", Wn());
03855 fprintf(fp, " use=");
03856 Print_use(Wn(), fp);
03857 break;
03858 case PHI_STMT:
03859 fprintf(fp, "Phi *0x%p ", Phi());
03860 fprintf(fp, " use=");
03861 Print_use(Phi(), Bb(), fp);
03862 if (!Phi()->Live())
03863 fprintf(fp, "^");
03864 else
03865 fprintf(fp, "ref_wn: 0x%p", Ref_wn());
03866 break;
03867 case CHI_STMT:
03868 fprintf(fp, "Chi *0x%p ", Chi());
03869 fprintf(fp, " use=%d", Chi()->Opnd());
03870 break;
03871 default:
03872 break;
03873 }
03874 fprintf(fp,"\n");
03875 }
03876
03877
03878 static inline BOOL
03879 Overlap(INT64 offset1, INT64 size1,
03880 INT64 offset2, INT64 size2)
03881 {
03882 return ((offset1 + size1 > offset2) &&
03883 (offset2 + size2 > offset1));
03884 }
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901 static ST_TAB *
03902 Find_symtab_of(const ST *st)
03903 {
03904 return Scope_tab[ST_IDX_level(ST_st_idx(st))].st_tab;
03905 }
03906
03907
03908 struct NEST_REF_CAND {
03909 INT64 offset;
03910 INT64 size;
03911 AUX_ID aux_id;
03912
03913 NEST_REF_CAND(void) { }
03914
03915 NEST_REF_CAND(INT64 ofst,
03916 INT64 sz,
03917 AUX_ID id) : offset(ofst), size(sz), aux_id(id) { }
03918 };
03919
03920
03921 struct transfer_attributes_as_needed {
03922 BOOL tracing;
03923 OPT_STAB *opt_stab;
03924 vector<vector<NEST_REF_CAND> > &nest_ref_cands;
03925 vector<const ST *> &nested_ref_bases;
03926
03927 transfer_attributes_as_needed(BOOL trace,
03928 OPT_STAB *stab,
03929 vector<vector<NEST_REF_CAND> > &cands,
03930 vector<const ST *> &bases) :
03931 tracing(trace),
03932 opt_stab(stab),
03933 nest_ref_cands(cands),
03934 nested_ref_bases(bases) { }
03935
03936 void operator()(UINT, ST *st) const
03937 {
03938 if (ST_class(st) == CLASS_VAR &&
03939 ST_has_nested_ref(st)) {
03940 ST *base;
03941 INT64 offset;
03942 Expand_ST_into_base_and_ofst(st, 0, &base, &offset);
03943 if (base != st) {
03944
03945 const ST **var_base_pos = &(*find(nested_ref_bases.begin(),
03946 nested_ref_bases.end(),
03947 base));
03948 if (var_base_pos != &(*nested_ref_bases.end())) {
03949
03950
03951
03952 INT var_base_index = (var_base_pos -
03953 &(*nested_ref_bases.begin()));
03954 const NEST_REF_CAND *first_nrc =
03955 &(*nest_ref_cands[var_base_index].begin());
03956 const NEST_REF_CAND *last_nrc =
03957 &(*nest_ref_cands[var_base_index].end());
03958 while (first_nrc != last_nrc) {
03959 if (Overlap(offset, TY_size(ST_type(st)),
03960 first_nrc->offset, first_nrc->size)) {
03961
03962
03963 Is_Trace(tracing, (TFile, "Setting nested ref bit "
03964 "on aux_id %d because of\n",
03965 first_nrc->aux_id));
03966 Is_Trace_cmd(tracing, Print_ST(TFile,
03967 (ST *) *var_base_pos,
03968 TRUE));
03969 opt_stab->Aux_stab_entry(first_nrc->aux_id)->
03970 Set_has_nested_ref();
03971 }
03972 ++first_nrc;
03973 }
03974 }
03975 }
03976 }
03977 }
03978 };
03979
03980
03981 void
03982 OPT_STAB::Collect_nested_ref_info(void)
03983 {
03984 BOOL tracing = Get_Trace(TP_GLOBOPT, ALIAS_DUMP_FLAG);
03985
03986 AUX_ID var;
03987 AUX_STAB_ITER aux_stab_iter(this);
03988
03989 vector <ST_TAB *> symtabs;
03990
03991 vector<const ST *> nested_ref_bases;
03992
03993
03994 vector<vector<NEST_REF_CAND> > nest_ref_cands;
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009 FOR_ALL_NODE(var, aux_stab_iter, Init()) {
04010 ST *var_base;
04011
04012 if (!Aux_stab_entry(var)->Has_nested_ref() &&
04013 (ST_class(var_base = Aux_stab_entry(var)->Base()) == CLASS_VAR) &&
04014 ST_has_nested_ref(var_base)) {
04015 Is_Trace(tracing, (TFile, "Found non-nested-ref symbol "
04016 "with nested_ref base:\n"));
04017 Is_Trace_cmd(tracing, Print_ST(TFile, Aux_stab_entry(var)->St(), TRUE));
04018 Is_Trace_cmd(tracing, Print_ST(TFile, var_base, TRUE));
04019
04020 ST_TAB *my_symtab = Find_symtab_of(var_base);
04021
04022 const ST **var_base_pos = &(*find(nested_ref_bases.begin(),
04023 nested_ref_bases.end(),
04024 var_base));
04025 INT var_base_index = var_base_pos - &(*nested_ref_bases.begin());
04026
04027 if (var_base_pos ==
04028 &(*nested_ref_bases.end())) {
04029 Is_True(nested_ref_bases.end() - nested_ref_bases.begin() ==
04030 var_base_index,
04031 ("Robert misunderstood STL vector: %d vs. %d",
04032 nested_ref_bases.end() - nested_ref_bases.begin(),
04033 var_base_index));
04034 nested_ref_bases.push_back(var_base);
04035
04036
04037 nest_ref_cands.push_back(vector<NEST_REF_CAND>());
04038
04039
04040
04041 if (find(symtabs.begin(), symtabs.end(), my_symtab) ==
04042 symtabs.end()) {
04043 symtabs.push_back(my_symtab);
04044 }
04045 }
04046
04047 NEST_REF_CAND nrc;
04048 ST *base;
04049 Expand_ST_into_base_and_ofst(Aux_stab_entry(var)->St(),
04050 Aux_stab_entry(var)->St_ofst(),
04051 &base, &nrc.offset);
04052 nrc.size = Aux_stab_entry(var)->Byte_size();
04053 nrc.aux_id = var;
04054
04055 nest_ref_cands[var_base_index].push_back(nrc);
04056 }
04057 }
04058
04059 ST_TAB **symtab;
04060
04061 for (symtab = &(*symtabs.begin());
04062 symtab != &(*symtabs.end());
04063 symtab++) {
04064 For_all_entries(**symtab,
04065 transfer_attributes_as_needed(tracing, this,
04066 nest_ref_cands,
04067 nested_ref_bases),
04068 1);
04069 }
04070 }
04071
04072
04073 void
04074 VER_STAB_ENTRY::Print_use(WN *wn, FILE *fp) const
04075 {
04076 OPERATOR opr = WN_operator(wn);
04077
04078 if (OPERATOR_has_aux(opr) && OPERATOR_is_scalar_load (opr)) {
04079 fprintf(fp, "%d ", WN_ver(wn));
04080 }
04081 for (INT32 i = 0; i < WN_kid_count(wn); i++)
04082 Print_use(WN_kid(wn,i), fp);
04083 }
04084
04085
04086 void
04087 VER_STAB_ENTRY::Print_use(PHI_NODE *phi, BB_NODE *bb, FILE *fp) const
04088 {
04089 INT32 in_degree = bb->Pred()->Len();
04090 for (INT32 i = 0; i < in_degree; i++) {
04091 fprintf(fp, "%d ", phi->Opnd(i));
04092 }
04093 }
04094
04095
04096
04097
04098 BOOL
04099 AUX_STAB_ENTRY::Has_def_by_const(void)
04100 {
04101 CODEREP *cr;
04102 CODEREP_ITER cr_iter;
04103 STMTREP *stmt;
04104 FOR_ALL_NODE(cr, cr_iter, Init(Cr_list())) {
04105 if (cr->Is_flag_set((CR_FLAG)(CF_DEF_BY_PHI | CF_DEF_BY_CHI |
04106 CF_IS_ZERO_VERSION)))
04107 continue;
04108 stmt = cr->Defstmt();
04109 Is_True(OPERATOR_is_scalar_store (stmt->Opr()),
04110 ("AUX_STAB_ENTRY::Has_def_by_const: not defined by STID"));
04111 if (inCODEKIND(stmt->Rhs()->Kind(), CK_LDA|CK_RCONST|CK_CONST))
04112 return TRUE;
04113 }
04114 return FALSE;
04115 }
04116
04117
04118
04119
04120
04121
04122 void COMP_UNIT::Do_local_rvi(void)
04123 {
04124 AUX_ID i;
04125 OPT_STAB *opt_stab = Opt_stab();
04126 AUX_STAB_ITER aux_stab_iter(opt_stab);
04127
04128 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
04129 AUX_STAB_ENTRY *var = opt_stab->Aux_stab_entry(i);
04130 if (var->Is_local_rvi_candidate( opt_stab->Is_varargs_func() )) {
04131 if (var->Has_def_by_const()) {
04132 if (WOPT_Enable_Shrink)
04133 var->Set_lr_shrink_cand();
04134 }
04135 else {
04136 if (WOPT_Enable_Local_Rvi_Limit != -1 &&
04137 i > WOPT_Enable_Local_Rvi_Limit)
04138 DevWarn("Do_local_rvi: skip aux_id > %d",
04139 WOPT_Enable_Local_Rvi_Limit);
04140 else var->Change_to_new_preg(opt_stab,Htable());
04141 }
04142 }
04143 }
04144 }
04145
04146
04147
04148
04149
04150
04151 void COMP_UNIT::Find_lr_shrink_cand(void)
04152 {
04153 if (! WOPT_Enable_Shrink)
04154 return;
04155
04156 AUX_ID i;
04157 OPT_STAB *opt_stab = Opt_stab();
04158 AUX_STAB_ITER aux_stab_iter(opt_stab);
04159
04160 FOR_ALL_NODE(i, aux_stab_iter, Init()) {
04161 AUX_STAB_ENTRY *var = opt_stab->Aux_stab_entry(i);
04162 if (var->Is_local_rvi_candidate( opt_stab->Is_varargs_func() )) {
04163 if (var->Has_def_by_const())
04164 var->Set_lr_shrink_cand();
04165 }
04166 }
04167 }
04168
04169
04170 BOOL OPT_STAB::Safe_to_speculate(AUX_ID id)
04171 {
04172 return Aux_stab_entry(id)->Points_to()->Safe_to_speculate();
04173 }
04174
04175 #ifdef KEY
04176
04177
04178 AUX_ID OPT_STAB::Part_of_reg_size_symbol(AUX_ID x)
04179 {
04180 if (! WOPT_Enable_Subword_Opt)
04181 return 0;
04182 AUX_ID cur;
04183 if (aux_stab[x].St_group()) {
04184 for (cur = aux_stab[x].St_group();
04185 cur != x;
04186 cur = aux_stab[cur].St_group()) {
04187 if (aux_stab[cur].Base() != aux_stab[x].Base())
04188 continue;
04189 if (aux_stab[cur].No_register() || aux_stab[cur].Has_nested_ref())
04190 continue;
04191 if (aux_stab[cur].Byte_size() != 4 && aux_stab[cur].Byte_size() != 8)
04192 continue;
04193 if ((aux_stab[cur].Mclass() & MTYPE_CLASS_INTEGER) == 0)
04194 continue;
04195 if (ST_sclass(aux_stab[cur].St()) != SCLASS_REG &&
04196 ST_sclass(aux_stab[cur].St()) != SCLASS_AUTO)
04197 continue;
04198 if (aux_stab[cur].Bit_size() != 0)
04199 continue;
04200 if (ST_is_temp_var(aux_stab[cur].St()))
04201 continue;
04202 if (aux_stab[cur].Is_volatile())
04203 continue;
04204 if (aux_stab[cur].Base_byte_ofst() <= aux_stab[x].Base_byte_ofst() &&
04205 (aux_stab[cur].Base_byte_ofst() + aux_stab[cur].Byte_size()) >=
04206 (aux_stab[x].Base_byte_ofst() + aux_stab[x].Byte_size()))
04207 break;
04208 }
04209 if (cur != x)
04210 return cur;
04211 }
04212 return 0;
04213 }
04214 #endif
04215
04216