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
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 #ifdef USE_PCH
00293 #include "opt_pch.h"
00294 #endif // USE_PCH
00295 #pragma hdrstop
00296
00297
00298 #define opt_main_CXX "opt_main.cxx"
00299
00300 #define __STDC_LIMIT_MACROS
00301 #include <stdint.h>
00302 #define USE_STANDARD_TYPES
00303 #include <alloca.h>
00304 #include "pu_info.h"
00305
00306 #include "unistd.h"
00307
00308 #include "defs.h"
00309 #include "erbe.h"
00310 #include "glob.h"
00311 #include "config_targ.h"
00312 #include "config_ipa.h"
00313 #include "config.h"
00314 #include "wn.h"
00315 #include "wn_simp.h"
00316 #include "wn_lower.h"
00317
00318 #include "wn_util.h"
00319
00320 #include "ir_reader.h"
00321 #include "tracing.h"
00322 #include "be_util.h"
00323 #include "region_util.h"
00324 #include "fb_whirl.h"
00325
00326 #include "optimizer.h"
00327 #include "opt_alias_class.h"
00328 #include "opt_cfg.h"
00329 #include "opt_main.h"
00330 #include "opt_fb.h"
00331 #include "opt_exc.h"
00332 #include "opt_sym.h"
00333 #include "opt_ssa.h"
00334 #include "opt_emit.h"
00335 #include "opt_du.h"
00336
00337 #include "opt_dbg.h"
00338 #include "opt_goto.h"
00339 #include "opt_rvi.h"
00340 #include "opt_util.h"
00341 #include "opt_alias_mgr.h"
00342 #include "opt_alias_interface.h"
00343 #include "opt_vn.h"
00344
00345 #include "config_lno.h"
00346 #include "config_opt.h"
00347
00348 #include "dep_graph.h"
00349 #include "wb_ipl.h"
00350
00351 #ifndef __MINGW32__
00352 #include "regex.h"
00353 #endif
00354 #include "xstats.h"
00355 #include "opt_wovp.h"
00356 #include "opt_misc.h"
00357 #include "opt_lmv.h"
00358 #include "opt_lmv_helper.h"
00359 #if defined(TARG_SL)
00360 #include "opt_lclsc.h"
00361 #endif
00362
00363 extern "C" void
00364 Perform_Procedure_Summary_Phase (WN* w, struct DU_MANAGER *du_mgr,
00365 struct ALIAS_MANAGER *alias_mgr,
00366 EMITTER *emitter);
00367 #if defined(__linux__) || defined(BUILD_OS_DARWIN) || !defined(SHARED_BUILD)
00368 extern void (*Perform_Procedure_Summary_Phase_p) (WN*, DU_MANAGER*,
00369 ALIAS_MANAGER*, void*);
00370 #define Perform_Procedure_Summary_Phase (*Perform_Procedure_Summary_Phase_p)
00371 #else
00372 #pragma weak Perform_Procedure_Summary_Phase
00373 #endif // __linux__
00374
00375 extern BOOL Enable_WN_Simp;
00376 extern void Simplify_bool_expr(COMP_UNIT *);
00377 extern void WN_unroll(WN *);
00378
00379 static MEM_POOL Opt_global_pool;
00380 static MEM_POOL Opt_local_pool;
00381 static ST *Opt_current_pu_st = NULL;
00382 static PU_IDX Opt_current_pu;
00383
00384 static void Opt_memory_init_pools(void)
00385 {
00386 OPT_POOL_Initialize(&Opt_global_pool, "Opt_global_pool", FALSE,
00387 MEM_DUMP_FLAG + 1);
00388 OPT_POOL_Initialize(&Opt_local_pool, "Opt_local_pool", FALSE,
00389 MEM_DUMP_FLAG + 1);
00390 OPT_POOL_Push(&Opt_global_pool, MEM_DUMP_FLAG+1);
00391 OPT_POOL_Push(&Opt_local_pool, MEM_DUMP_FLAG+1);
00392 }
00393
00394 static void Opt_memory_terminate_pools(void)
00395 {
00396 OPT_POOL_Pop(&Opt_global_pool, MEM_DUMP_FLAG+1);
00397 OPT_POOL_Pop(&Opt_local_pool, MEM_DUMP_FLAG+1);
00398 OPT_POOL_Delete(&Opt_global_pool, MEM_DUMP_FLAG+1);
00399 OPT_POOL_Delete(&Opt_local_pool, MEM_DUMP_FLAG+1);
00400 }
00401
00402 static void Opt_set_current_pu_name(WN *wn_tree)
00403 {
00404 Is_True(wn_tree != NULL && (WN_opcode(wn_tree) == OPC_REGION ||
00405 WN_opcode(wn_tree) == OPC_FUNC_ENTRY),
00406 ("Opt_set_current_pu_name, unknown WN"));
00407 ST *st;
00408 if (WN_opcode(wn_tree) == OPC_REGION) {
00409
00410 WN *pu = REGION_find_pu(wn_tree);
00411 Is_True(pu != NULL && WN_opcode(pu) == OPC_FUNC_ENTRY,
00412 ("Opt_set_current_pu_name, could not find func entry"));
00413 st = WN_st(pu);
00414 } else {
00415 st = WN_st(wn_tree);
00416 }
00417
00418 if (Opt_current_pu_st == NULL) {
00419 Opt_current_pu_st = st;
00420 Opt_current_pu = ST_pu(st);
00421 }
00422 else if (st != Opt_current_pu_st) {
00423 Opt_current_pu_st = st;
00424 Opt_current_pu = ST_pu(st);
00425 }
00426 else {
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 class WOPT_SWITCHES {
00457 private:
00458 OPT_PHASE _phase;
00459 INT32 _pragma_flags;
00460 BOOL _add_do_loop_info;
00461 BOOL _add_label_loop_info;
00462 BOOL _addr;
00463 BOOL _aggressive_dce;
00464 BOOL _aggressive_code_motion;
00465 BOOL _alias_classification;
00466 BOOL _alias_class_fortran_rule;
00467 BOOL _alias_pointer_parms;
00468 BOOL _combine_operations;
00469 BOOL _call_zero_version;
00470 BOOL _compare_simp;
00471 INT32 _copy_propagate;
00472 BOOL _copy_prop_into_array;
00473 BOOL _crsimp;
00474 BOOL _dce;
00475 BOOL _dce_alias;
00476 BOOL _dce_label;
00477 BOOL _dse_aggressive;
00478 BOOL _du_full;
00479 BOOL _edge_placement;
00480 BOOL _exp_pre;
00481 BOOL _fold2const;
00482 BOOL _lno_copy;
00483 BOOL _fsa;
00484 BOOL _goto;
00485 BOOL _iload_prop;
00486 BOOL _input_prop;
00487 BOOL _itself_prop;
00488 BOOL _ivar_common;
00489 BOOL _ive;
00490 BOOL _ivr;
00491 BOOL _ldx;
00492 BOOL _lego_opt;
00493 BOOL _load_pre;
00494 BOOL _local_rvi;
00495 BOOL _ocopy;
00496 BOOL _parm;
00497 BOOL _phi_simp;
00498 BOOL _prop_aggressive;
00499 BOOL _replace_second_iv;
00500 BOOL _restricted_map;
00501 BOOL _rvi;
00502 BOOL _simp_iload;
00503 BOOL _slt;
00504 BOOL _store_pre;
00505 BOOL _ssa_pre;
00506 BOOL _tail_recur;
00507 INT32 _trip;
00508 BOOL _update_vsym;
00509 INT32 _value_numbering;
00510 BOOL _verbose;
00511 INT32 _verify;
00512 BOOL _vn_full;
00513 BOOL _vsym_unique;
00514 BOOL _while_loop;
00515 BOOL _wn_simp;
00516 BOOL _wovp;
00517 BOOL _zero_version;
00518 BOOL _epre_before_ivr;
00519 BOOL _lpre_before_ivr;
00520 BOOL _spre_before_ivr;
00521 BOOL _bdce_before_ivr;
00522 BOOL _loop_multiver;
00523
00524 WOPT_SWITCHES(const WOPT_SWITCHES&);
00525 WOPT_SWITCHES& operator = (const WOPT_SWITCHES&);
00526 void Adjust_Optimization(void) {
00527 switch (_phase) {
00528 case PREOPT_DUONLY_PHASE:
00529
00530 WOPT_Enable_Add_Do_Loop_Info =
00531 WOPT_Enable_Add_Label_Loop_Info =
00532 WOPT_Enable_Aggressive_dce =
00533 WOPT_Enable_Aggressive_Code_Motion =
00534 WOPT_Enable_Alias_Classification =
00535 WOPT_Enable_Alias_Class_Fortran_Rule =
00536 WOPT_Enable_Combine_Operations =
00537 WOPT_Enable_Compare_Simp =
00538 WOPT_Enable_CRSIMP =
00539 WOPT_Enable_DCE =
00540 WOPT_Enable_DCE_Alias =
00541 WOPT_Enable_Edge_Placement =
00542 WOPT_Enable_Exp_PRE =
00543 WOPT_Enable_Fold2const =
00544 WOPT_Enable_LNO_Copy_Propagate =
00545 WOPT_Enable_FSA =
00546 WOPT_Enable_Goto =
00547 WOPT_Enable_Input_Prop =
00548 WOPT_Enable_Itself_Prop =
00549 WOPT_Enable_Ivar_Common =
00550 WOPT_Enable_IVE =
00551 WOPT_Enable_IVR =
00552 WOPT_Enable_Ldx =
00553 WOPT_Enable_Load_PRE =
00554 WOPT_Enable_Local_Rvi =
00555 WOPT_Enable_Output_Copy =
00556 WOPT_Enable_Parm =
00557 WOPT_Enable_Phi_Simp =
00558 WOPT_Enable_RVI =
00559 WOPT_Enable_SLT =
00560 WOPT_Enable_Store_PRE =
00561 WOPT_Enable_SSA_PRE =
00562 WOPT_Enable_Vsym_Unique =
00563 WOPT_Enable_WOVP =
00564 Enable_WN_Simp =
00565
00566 WOPT_Enable_Tail_Recur =
00567 FALSE;
00568
00569 WOPT_Enable_Copy_Propagate = TRUE;
00570 WOPT_Enable_Verify = 1;
00571 break;
00572
00573 case PREOPT_IPA0_PHASE:
00574 case PREOPT_IPA1_PHASE:
00575 WOPT_Enable_Call_Zero_Version = FALSE;
00576 WOPT_Enable_Combine_Operations = FALSE;
00577 WOPT_Enable_Goto = FALSE;
00578 WOPT_Enable_WOVP = FALSE;
00579 WOPT_Enable_Tail_Recur = FALSE;
00580 break;
00581
00582 case MAINOPT_PHASE:
00583 WOPT_Enable_While_Loop = FALSE;
00584
00585
00586 if (! WOPT_Enable_SSA_PRE) {
00587 WOPT_Enable_Edge_Placement = FALSE;
00588 WOPT_Enable_Backedge_Placement = FALSE;
00589 }
00590 else {
00591 WOPT_Enable_RVI1 = FALSE;
00592 if (!WOPT_Enable_Exp_PRE && WOPT_Enable_Load_PRE) {
00593
00594 WOPT_Enable_Exp_PRE = TRUE;
00595 WOPT_Enable_Exp_PRE_Limit = 0;
00596 }
00597 }
00598
00599 if (Opt_Level > 2 && PU_mp_needs_lno(Get_Current_PU())) {
00600 WOPT_Enable_Lego_Opt = TRUE;
00601 }
00602
00603 if (Opt_Level <= 2) {
00604
00605 WOPT_Enable_Replace_Second_IV = FALSE;
00606
00607
00608 if (!WOPT_Enable_Extra_Rename_Pass_Set)
00609 WOPT_Enable_Extra_Rename_Pass = 1;
00610 }
00611
00612 if (WOPT_Enable_Lego_Opt) {
00613 WOPT_Enable_Compare_Simp = TRUE;
00614 WOPT_Enable_Replace_Second_IV = TRUE;
00615 WOPT_Enable_LFTR_Ivar = TRUE;
00616
00617 }
00618
00619
00620 if ( ! Allow_wrap_around_opt ) {
00621 WOPT_Enable_LFTR2 = FALSE;
00622 WOPT_Enable_Compare_Simp = FALSE;
00623 WOPT_Enable_IVR = FALSE;
00624 }
00625
00626
00627 Enable_WN_Simp = FALSE;
00628
00629
00630 WOPT_Enable_LNO_Copy_Propagate = FALSE;
00631
00632
00633 WOPT_Enable_Combine_Operations = _combine_operations;
00634
00635
00636 WOPT_Enable_DCE_Label = FALSE;
00637
00638
00639 if ( ! WOPT_Enable_Copy_Prop_Ops_Into_Array_Set )
00640 WOPT_Enable_Copy_Prop_Ops_Into_Array = TRUE;
00641
00642 if (WOPT_Enable_Feedback_LPRE || WOPT_Enable_Feedback_EPRE)
00643 WOPT_Enable_Zero_Version = FALSE;
00644
00645 break;
00646
00647 #ifdef TARG_NVISA
00648 case PREOPT_CMC_PHASE:
00649 WOPT_Enable_Goto = TRUE;
00650 WOPT_Enable_Call_Zero_Version = FALSE;
00651 WOPT_Enable_Zero_Version = FALSE;
00652 WOPT_Enable_DU_Full = TRUE;
00653 WOPT_Enable_Copy_Propagate = TRUE;
00654 break;
00655 #endif
00656
00657 case PREOPT_LNO_PHASE:
00658 if (Run_autopar && Current_LNO->IPA_Enabled
00659 #ifdef KEY
00660 && PU_WN_BB_Cnt < 2000
00661 #endif
00662 ) {
00663 WOPT_Enable_Call_Zero_Version = FALSE;
00664 WOPT_Enable_Zero_Version = FALSE;
00665 WOPT_Enable_DU_Full = TRUE;
00666 }
00667
00668 default:
00669
00670 if ( ! Allow_wrap_around_opt ) {
00671 WOPT_Enable_Compare_Simp = FALSE;
00672 WOPT_Enable_IVR = FALSE;
00673 }
00674 WOPT_Enable_Combine_Operations = FALSE;
00675 WOPT_Enable_SLT = FALSE;
00676 break;
00677 }
00678 WOPT_Enable_Ldx = Indexed_Loads_Allowed;
00679
00680 if (_pragma_flags & WOPT_TAIL_RECUR_FINISHED)
00681 WOPT_Enable_Tail_Recur = FALSE;
00682
00683 if (_phase != MAINOPT_PHASE || !WOPT_Enable_New_Phase_Ordering)
00684 {
00685 WOPT_Enable_Epre_Before_Ivr = FALSE;
00686 WOPT_Enable_Lpre_Before_Ivr = FALSE;
00687 WOPT_Enable_Spre_Before_Ivr = FALSE;
00688 WOPT_Enable_Bdce_Before_Ivr = FALSE;
00689 }
00690
00691 if (_phase != PREOPT_LNO_PHASE) WOPT_Enable_Loop_Multiver = FALSE;
00692 }
00693
00694 void Unadjust_Optimization(void) {
00695 switch (_phase) {
00696 case PREOPT_DUONLY_PHASE:
00697
00698 WOPT_Enable_Compare_Simp = _compare_simp;
00699 WOPT_Enable_Add_Do_Loop_Info = _add_do_loop_info;
00700 WOPT_Enable_Add_Label_Loop_Info = _add_label_loop_info;
00701 WOPT_Enable_Aggressive_dce = _aggressive_dce;
00702 WOPT_Enable_Aggressive_Code_Motion = _aggressive_code_motion;
00703 WOPT_Enable_Alias_Classification = _alias_classification;
00704 WOPT_Enable_Alias_Class_Fortran_Rule = _alias_class_fortran_rule;
00705 WOPT_Enable_Copy_Propagate = _copy_propagate;
00706 WOPT_Enable_CRSIMP = _crsimp;
00707 WOPT_Enable_DCE = _dce;
00708 WOPT_Enable_DCE_Alias = _dce_alias;
00709 WOPT_Enable_DU_Full = _du_full;
00710 WOPT_Enable_Edge_Placement = _edge_placement;
00711 WOPT_Enable_Exp_PRE = _exp_pre;
00712 WOPT_Enable_Fold2const = _fold2const;
00713 WOPT_Enable_FSA = _fsa;
00714 WOPT_Enable_Generate_Trip_Count = _trip;
00715 WOPT_Enable_Improved_Addr_Taken = _addr;
00716 WOPT_Enable_Input_Prop = _input_prop;
00717 WOPT_Enable_Ivar_Common = _ivar_common;
00718 WOPT_Enable_IVE = _ive;
00719 WOPT_Enable_IVR = _ivr;
00720 WOPT_Enable_Ldx = _ldx;
00721 WOPT_Enable_LNO_Copy_Propagate = _lno_copy;
00722 WOPT_Enable_Load_PRE = _load_pre;
00723 WOPT_Enable_Local_Rvi = _local_rvi;
00724 WOPT_Enable_Output_Copy = _ocopy;
00725 WOPT_Enable_Parm = _parm;
00726 WOPT_Enable_Phi_Simp = _phi_simp;
00727 WOPT_Enable_RVI = _rvi;
00728 WOPT_Enable_Store_PRE = _store_pre;
00729 WOPT_Enable_SSA_PRE = _ssa_pre;
00730 WOPT_Enable_Verify = _verify;
00731 WOPT_Enable_Vsym_Unique = _vsym_unique;
00732 WOPT_Enable_WOVP = _wovp;
00733 WOPT_Enable_Zero_Version = _zero_version;
00734 WOPT_Enable_Epre_Before_Ivr = _epre_before_ivr;
00735 break;
00736 case PREOPT_IPA0_PHASE:
00737 case PREOPT_IPA1_PHASE:
00738 WOPT_Enable_Compare_Simp = _compare_simp;
00739 WOPT_Enable_IVR = _ivr;
00740 WOPT_Enable_SLT = _slt;
00741 WOPT_Enable_WOVP = _wovp;
00742 break;
00743 case MAINOPT_PHASE:
00744 WOPT_Enable_Compare_Simp = _compare_simp;
00745 WOPT_Enable_Copy_Prop_Ops_Into_Array = _copy_prop_into_array;
00746 WOPT_Enable_CRSIMP = _crsimp;
00747 WOPT_Enable_DCE_Label = _dce_label;
00748 WOPT_Enable_IVR = _ivr;
00749 WOPT_Enable_Lego_Opt = _lego_opt;
00750 WOPT_Enable_While_Loop = _while_loop;
00751 WOPT_Enable_Improved_Addr_Taken = _addr;
00752 WOPT_Enable_Generate_Trip_Count = _trip;
00753 WOPT_Enable_LNO_Copy_Propagate = _lno_copy;
00754 WOPT_Enable_Zero_Version = _zero_version;
00755 break;
00756 #ifdef TARG_NVISA
00757 case PREOPT_CMC_PHASE:
00758 WOPT_Enable_Goto = _goto;
00759 WOPT_Enable_Call_Zero_Version = _call_zero_version;
00760 WOPT_Enable_Zero_Version = _zero_version;
00761 WOPT_Enable_DU_Full = _du_full;
00762 break;
00763 #endif
00764 case PREOPT_LNO_PHASE:
00765 if (Run_autopar && Current_LNO->IPA_Enabled) {
00766 WOPT_Enable_Call_Zero_Version = _call_zero_version;
00767 WOPT_Enable_Zero_Version = _zero_version;
00768 WOPT_Enable_DU_Full = _du_full;
00769 }
00770 default:
00771 WOPT_Enable_SLT = _slt;
00772 break;
00773 }
00774
00775 Enable_WN_Simp = _wn_simp;
00776 WOPT_Enable_Goto = _goto;
00777 WOPT_Enable_Combine_Operations = _combine_operations;
00778 WOPT_Enable_Tail_Recur = _tail_recur;
00779 WOPT_Enable_Replace_Second_IV = _replace_second_iv;
00780 WOPT_Enable_Restricted_Map = _restricted_map;
00781 WOPT_Enable_Value_Numbering = _value_numbering;
00782 WOPT_Enable_Itself_Prop = _itself_prop;
00783
00784 WOPT_Enable_Epre_Before_Ivr = _epre_before_ivr;
00785 WOPT_Enable_Lpre_Before_Ivr = _lpre_before_ivr;
00786 WOPT_Enable_Spre_Before_Ivr = _spre_before_ivr;
00787 WOPT_Enable_Bdce_Before_Ivr = _bdce_before_ivr;
00788
00789 Alias_Pointer_Parms = _alias_pointer_parms;
00790 WOPT_Enable_Loop_Multiver = _loop_multiver;
00791 }
00792
00793 public:
00794 WOPT_SWITCHES(OPT_PHASE phase, INT32 pragma_flags, BOOL disable_parm_alias) {
00795 _phase = phase;
00796 _pragma_flags = pragma_flags;
00797
00798 _alias_pointer_parms = Alias_Pointer_Parms;
00799 if (disable_parm_alias)
00800 Alias_Pointer_Parms = FALSE;
00801
00802 _add_do_loop_info = WOPT_Enable_Add_Do_Loop_Info;
00803 _add_label_loop_info = WOPT_Enable_Add_Label_Loop_Info;
00804 _addr = WOPT_Enable_Improved_Addr_Taken;
00805 _aggressive_dce = WOPT_Enable_Aggressive_dce;
00806 _aggressive_code_motion = WOPT_Enable_Aggressive_Code_Motion;
00807 _alias_classification = WOPT_Enable_Alias_Classification;
00808 _alias_class_fortran_rule = WOPT_Enable_Alias_Class_Fortran_Rule;
00809 _call_zero_version = WOPT_Enable_Call_Zero_Version;
00810 _combine_operations = WOPT_Enable_Combine_Operations;
00811 _compare_simp = WOPT_Enable_Compare_Simp;
00812 _copy_propagate = WOPT_Enable_Copy_Propagate;
00813 _copy_prop_into_array = WOPT_Enable_Copy_Prop_Ops_Into_Array;
00814 _crsimp = WOPT_Enable_CRSIMP;
00815 _dce = WOPT_Enable_DCE;
00816 _dce_alias = WOPT_Enable_DCE_Alias;
00817 _dce_label = WOPT_Enable_DCE_Label;
00818 _du_full = WOPT_Enable_DU_Full;
00819 _edge_placement = WOPT_Enable_Edge_Placement;
00820 _exp_pre = WOPT_Enable_Exp_PRE;
00821 _fold2const = WOPT_Enable_Fold2const;
00822 _lno_copy = WOPT_Enable_LNO_Copy_Propagate;
00823 _fsa = WOPT_Enable_FSA;
00824 _goto = WOPT_Enable_Goto;
00825 _input_prop = WOPT_Enable_Input_Prop;
00826 _itself_prop = WOPT_Enable_Itself_Prop;
00827 _ivar_common = WOPT_Enable_Ivar_Common;
00828 _ive = WOPT_Enable_IVE;
00829 _ivr = WOPT_Enable_IVR;
00830 _ldx = Indexed_Loads_Allowed;
00831 _lego_opt = WOPT_Enable_Lego_Opt;
00832
00833 _load_pre = WOPT_Enable_Load_PRE;
00834 _local_rvi = WOPT_Enable_Local_Rvi;
00835 _ocopy = WOPT_Enable_Output_Copy;
00836 _parm = WOPT_Enable_Parm;
00837 _phi_simp = WOPT_Enable_Phi_Simp;
00838 _rvi = WOPT_Enable_RVI;
00839 _slt = WOPT_Enable_SLT;
00840 _store_pre = WOPT_Enable_Store_PRE;
00841 _ssa_pre = WOPT_Enable_SSA_PRE;
00842 _trip = WOPT_Enable_Generate_Trip_Count;
00843 _update_vsym = WOPT_Enable_Update_Vsym;
00844 _value_numbering = WOPT_Enable_Value_Numbering;
00845 _verbose = WOPT_Enable_Verbose;
00846 _vsym_unique = WOPT_Enable_Vsym_Unique;
00847 _verify = WOPT_Enable_Verify;
00848 _while_loop = WOPT_Enable_While_Loop;
00849 _wn_simp = Enable_WN_Simp;
00850 _wovp = WOPT_Enable_WOVP;
00851 _zero_version = WOPT_Enable_Zero_Version;
00852 _vsym_unique = WOPT_Enable_Vsym_Unique;
00853 _dse_aggressive = WOPT_Enable_Dse_Aggressive;
00854 _prop_aggressive = WOPT_Enable_Prop_Aggressive;
00855 _iload_prop = WOPT_Enable_Iload_Prop;
00856 _vn_full = WOPT_Enable_VN_Full;
00857 _simp_iload = WOPT_Enable_Simp_Iload;
00858 _tail_recur = WOPT_Enable_Tail_Recur;
00859 _replace_second_iv = WOPT_Enable_Replace_Second_IV;
00860 _restricted_map = WOPT_Enable_Restricted_Map;
00861 _epre_before_ivr = WOPT_Enable_Epre_Before_Ivr;
00862 _lpre_before_ivr = WOPT_Enable_Lpre_Before_Ivr;
00863 _spre_before_ivr = WOPT_Enable_Spre_Before_Ivr;
00864 _bdce_before_ivr = WOPT_Enable_Bdce_Before_Ivr;
00865 _loop_multiver = WOPT_Enable_Loop_Multiver;
00866
00867 Adjust_Optimization();
00868 }
00869 ~WOPT_SWITCHES(void) { Unadjust_Optimization(); }
00870
00871 };
00872
00873
00874
00875 COMP_UNIT::COMP_UNIT(WN *t, ALIAS_MANAGER *am, OPT_PHASE phase,
00876 MEM_POOL *gpool,MEM_POOL *lpool)
00877 {
00878 extern void Initialize_CR_simp(CODEMAP*);
00879
00880 _phase = phase;
00881 Set_tlog_phase(phase);
00882 _mem_pool = gpool;
00883 _loc_pool = lpool;
00884 _input_tree = t;
00885 _rid = REGION_get_rid(_input_tree);
00886 _arule = am->Rule();
00887 _alias_mgr = am;
00888 _cfg = CXX_NEW(CFG(gpool, lpool), gpool);
00889 _opt_stab = CXX_NEW(OPT_STAB(gpool), gpool);
00890 _exc = CXX_NEW(EXC(_cfg, _opt_stab, gpool), gpool);
00891 _cfg->Set_exc(_exc);
00892 _ssa = CXX_NEW(SSA(gpool, lpool), gpool);
00893 _emitter = CXX_NEW(EMITTER(lpool, gpool, phase), gpool);
00894 _htable = CXX_NEW(CODEMAP(CODE_HTABLE_SIZE, _cfg,
00895 _opt_stab, _ssa,
00896 VAR_PHI_HASH_SIZE, phase, gpool),
00897 gpool);
00898 _main_emitter = NULL;
00899 WN_init_flags(gpool);
00900 Initialize_CR_simp(_htable);
00901 VN_EXPR::Init_Free_Lists(gpool);
00902 }
00903
00904
00905
00906
00907 COMP_UNIT::~COMP_UNIT(void)
00908 {
00909 VN_EXPR::Reclaim_Free_Lists();
00910 WN_fini_flags();
00911 CXX_DELETE(_cfg, _mem_pool);
00912 CXX_DELETE(_opt_stab, _mem_pool);
00913 CXX_DELETE(_ssa, _mem_pool);
00914 CXX_DELETE(_emitter, _mem_pool);
00915 CXX_DELETE(_htable, _mem_pool);
00916 CXX_DELETE(_exc, _mem_pool);
00917 }
00918
00919
00920 void COMP_UNIT::Create_mainopt_res(void)
00921 {
00922 _cfg->Analyze_loops();
00923 }
00924
00925
00926
00927
00928
00929
00930 static BOOL Disable_opt(WN *wn_tree, ST *pu_st)
00931 {
00932 BOOL is_pu = (WN_opcode(wn_tree) == OPC_FUNC_ENTRY);
00933 char *pu_name = ST_name(pu_st);
00934 char *rgn_name = (char*)alloca(strlen(pu_name) + 32);
00935
00936 if (is_pu)
00937 sprintf(rgn_name,"function %s",pu_name);
00938 else
00939 sprintf(rgn_name,"region %d (function %s)",
00940 RID_id(REGION_get_rid(wn_tree)),pu_name);
00941
00942 #ifndef __MINGW32__
00943
00944 if (WOPT_Enable_Skip != NULL) {
00945 regex_t buf;
00946 regmatch_t dummy[1];
00947 if (regcomp(&buf, WOPT_Enable_Skip, REG_NOSUB | REG_NEWLINE) == 0 &&
00948 regexec(&buf, pu_name, 1, dummy, 0) == 0) {
00949 DevWarn("WOPT skip %s", rgn_name);
00950 return TRUE;
00951 }
00952 }
00953 #endif
00954
00955
00956 if ( Query_Skiplist ( WOPT_Skip_List, Current_PU_Count() ) ) {
00957 if ( Show_Progress )
00958 ErrMsg(EC_Skip_PU, " WOPT", Current_PU_Count(), rgn_name);
00959 return TRUE;
00960 }
00961
00962 #ifndef __MINGW32__
00963
00964 if (WOPT_Enable_Process != NULL) {
00965 regex_t buf;
00966 regmatch_t dummy[1];
00967 if (regcomp(&buf, WOPT_Enable_Process, REG_NOSUB | REG_NEWLINE) == 0 &&
00968 regexec(&buf, pu_name, 1, dummy, 0) == 0) {
00969 } else {
00970 DevWarn("WOPT skip %s", rgn_name);
00971 return TRUE;
00972 }
00973 }
00974 #endif
00975
00976 return FALSE;
00977 }
00978
00979 static BOOL
00980 This_preopt_renumbers_pregs(INT32 phase)
00981 {
00982 return ((((phase == PREOPT_IPA0_PHASE) &&
00983 IPA_Enable_Alias_Class) ||
00984 (phase == PREOPT_LNO_PHASE) ||
00985 (phase == PREOPT_PHASE)) &&
00986 !Is_Set_PU_Info_flags(Current_PU_Info,
00987 PU_PREGS_RENUMBERED));
00988 }
00989
00990
00991 static void
00992 Verify_Codemap(COMP_UNIT *comp_unit)
00993 {
00994 #ifdef Is_True_On
00995 SET_OPT_PHASE("Verify CODEMAP");
00996
00997 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(),comp_unit->Htable(),0),
00998 ("Verify CFG wrong"));
00999
01000 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01001 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01002 else
01003 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01004
01005 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01006 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01007 else {
01008 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01009 comp_unit->Htable()->Verify_hashing();
01010 }
01011
01012 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01013 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01014 } else {
01015 SET_OPT_PHASE("Verify Live-Range");
01016 comp_unit->Verify_version();
01017 }
01018 #endif // Is_True_On
01019 }
01020
01021
01022 extern void CFG_transformation(COMP_UNIT *cu, bool, bool, bool);
01023 extern void Rename_CODEMAP(COMP_UNIT *);
01024
01025
01026 static void
01027 Do_Pre_Before_Ivr(COMP_UNIT *comp_unit)
01028 {
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046 if (WOPT_Enable_Epre_Before_Ivr ||
01047 WOPT_Enable_Lpre_Before_Ivr ||
01048 WOPT_Enable_Spre_Before_Ivr ||
01049 WOPT_Enable_Bdce_Before_Ivr)
01050 {
01051 BOOL dummy;
01052 comp_unit->Do_dead_code_elim(FALSE,
01053 FALSE,
01054 FALSE,
01055 FALSE,
01056 FALSE,
01057 FALSE,
01058 &dummy);
01059 }
01060
01061
01062
01063
01064
01065 if (WOPT_Enable_Epre_Before_Ivr)
01066 {
01067 SET_OPT_PHASE("SSA PRE before RVI");
01068 comp_unit->Do_new_pre();
01069 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01070 comp_unit->Htable()->Print(TFile);
01071 }
01072 Verify_Codemap(comp_unit);
01073 }
01074 if (WOPT_Enable_Lpre_Before_Ivr)
01075 {
01076 SET_OPT_PHASE("Load PRE before RVI");
01077 comp_unit->Htable()->Verify_var_phi_hash();
01078 comp_unit->Do_load_pre(FALSE , TRUE );
01079
01080 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01081 comp_unit->Htable()->Print(TFile);
01082 }
01083 Verify_Codemap(comp_unit);
01084 }
01085 if (WOPT_Enable_Spre_Before_Ivr)
01086 {
01087 SET_OPT_PHASE("Store PRE before RVI");
01088 comp_unit->Htable()->Verify_var_phi_hash();
01089 comp_unit->Do_store_pre();
01090
01091 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01092 comp_unit->Htable()->Print(TFile);
01093 }
01094 Verify_Codemap(comp_unit);
01095 }
01096 if (WOPT_Enable_Bdce_Before_Ivr)
01097 {
01098 SET_OPT_PHASE("Bitwise DCE before RVI");
01099 comp_unit->Do_bitwise_dce(FALSE );
01100 }
01101
01102 if (WOPT_Enable_Epre_Before_Ivr || WOPT_Enable_Epre_Before_Ivr)
01103 {
01104 SET_OPT_PHASE("Second rename before RVI");
01105 Rename_CODEMAP(comp_unit);
01106 }
01107
01108 }
01109
01110
01111 WN *
01112 Pre_Optimizer(INT32 phase, WN *wn_tree, DU_MANAGER *du_mgr,
01113 ALIAS_MANAGER *alias_mgr)
01114 {
01115 WN *wn_orig = wn_tree;
01116
01117 SET_OPT_PHASE("Preparation");
01118
01119 if (Get_Trace(TP_GLOBOPT, -1)) {
01120 fprintf (TFile, "%s \t Pre_Optimizer phase=%d\n %s\n", DBar, phase, DBar);
01121 }
01122
01123 Is_True(phase == PREOPT_IPA0_PHASE ||
01124 phase == PREOPT_IPA1_PHASE ||
01125 phase == PREOPT_LNO_PHASE ||
01126 phase == PREOPT_DUONLY_PHASE ||
01127 phase == PREOPT_PHASE ||
01128 phase == MAINOPT_PHASE,
01129 ("Unknown optimizer phase."));
01130
01131 Is_True(WN_opcode(wn_orig)==OPC_FUNC_ENTRY || WN_opcode(wn_orig)==OPC_REGION,
01132 ("Pre_Optimizer, unknown WHIRL entry point"));
01133
01134
01135 Opt_set_current_pu_name(wn_tree);
01136
01137
01138 BOOL dont_opt = Disable_opt(wn_tree, Opt_current_pu_st);
01139
01140 WN *wopt_pragma = (WN_opcode(wn_orig) == OPC_FUNC_ENTRY) ?
01141 WN_func_pragmas(wn_orig) : WN_region_pragmas(wn_orig);
01142 INT32 pragma_flags = 0;
01143 BOOL disable_parm_alias = FALSE;
01144 for (wopt_pragma = WN_first(wopt_pragma);
01145 wopt_pragma != NULL;
01146 wopt_pragma = WN_next(wopt_pragma)) {
01147 if ( WN_pragma(wopt_pragma) == WN_PRAGMA_WOPT_FINISHED_OPT ) {
01148 pragma_flags = WN_pragma_arg2(wopt_pragma);
01149 }
01150 }
01151
01152 if (IS_FORTRAN && PU_args_aliased(Pu_Table[Opt_current_pu])) {
01153 disable_parm_alias = TRUE;
01154 }
01155
01156 WOPT_SWITCHES WOPT_Enable((OPT_PHASE)phase, pragma_flags,
01157 disable_parm_alias);
01158
01159
01160
01161 if (WN_opcode(wn_orig) != OPC_REGION) {
01162 if (PU_is_nested_func(Pu_Table[Opt_current_pu]) &&
01163 !PU_mp(Get_Current_PU()))
01164 WOPT_Enable_Restricted_Map = FALSE;
01165 }
01166
01167 BOOL Fold_ILOAD_save = WN_Simp_Fold_ILOAD;
01168 BOOL Fold_LDA_save = WN_Simp_Fold_LDA;
01169
01170 enable_tree_freq_display();
01171
01172
01173 if (phase == MAINOPT_PHASE) {
01174 SET_OPT_PHASE("Mainopt Lowering");
01175 WN_Simplifier_Enable(TRUE);
01176
01177 INT32 lower_region_exits_flag = ((PU_has_region(Get_Current_PU()) &&
01178 WN_opcode(wn_orig) == OPC_FUNC_ENTRY) ?
01179 LOWER_REGION_EXITS : 0);
01180 WN_Simp_Fold_ILOAD = TRUE;
01181 WN_Simp_Fold_LDA = TRUE;
01182 LOWER_ACTIONS actions =
01183 LOWER_COMPLEX |
01184 LOWER_BASE_INDEX |
01185 LOWER_ARRAY |
01186 LOWER_ALL_MAPS |
01187 LOWER_INLINE_INTRINSIC |
01188 LOWER_IO_STATEMENT |
01189 LOWER_ENTRY_EXIT |
01190 LOWER_SHORTCIRCUIT |
01191 #ifdef KEY
01192 LOWER_UPLEVEL |
01193 #endif
01194 lower_region_exits_flag;
01195
01196 if (WOPT_Enable_Bits_Load_Store)
01197 actions |= LOWER_BIT_FIELD_ID;
01198 else
01199 actions |= LOWER_BITS_OP;
01200
01201 actions |= LOWER_TO_MEMLIB;
01202
01203 wn_tree = WN_Lower(wn_orig, actions, alias_mgr, "Pre_Opt");
01204
01205 #if defined(TARG_X8664) || defined(TARG_NVISA)
01206 BOOL target_64bit = Is_Target_64bit();
01207 #elif defined(TARG_SL)
01208 BOOL target_64bit = FALSE;
01209 #else
01210 BOOL target_64bit = TRUE;
01211 #endif
01212
01213 #ifdef KEY
01214 if (target_64bit && WOPT_Enable_Retype_Expr)
01215 WN_retype_expr(wn_tree);
01216 #endif
01217
01218 #if defined(KEY) && !(defined(TARG_IA64) || defined(TARG_SL))
01219 WN_unroll(wn_tree);
01220 #endif
01221
01222 if (Cur_PU_Feedback)
01223 Cur_PU_Feedback->Reset_Root_WN(wn_tree);
01224 if (Only_Unsigned_64_Bit_Ops && ! Delay_U64_Lowering)
01225 U64_lower_wn(wn_tree, FALSE);
01226 Is_True(REGION_consistency_check(wn_tree),
01227 ("Pre_Optimizer REGION inconsistency"));
01228 wn_orig = wn_tree;
01229
01230
01231 if (dont_opt) return wn_tree;
01232
01233 WN_Simplifier_Enable(FALSE);
01234
01235 if ( Get_Trace( TP_GLOBOPT, OPT_LOWER_FLAG ) ) {
01236 fprintf( TFile, "%sAfter Mainopt Lowering\n%s",DBar,DBar );
01237 fdump_tree(TFile, wn_tree);
01238 }
01239
01240 if (phase == MAINOPT_PHASE && Current_Dep_Graph != NULL &&
01241 Get_Trace(TP_LNOPT, 1)) {
01242
01243 fprintf(TFile, "%sLNO dep graph for CG, before WOPT\n%s", DBar, DBar);
01244 Current_Dep_Graph->Print(TFile);
01245 fprintf(TFile, "%s", DBar);
01246 }
01247 }
01248 else {
01249 if ( Get_Trace( TP_GLOBOPT, OPT_LOWER_FLAG ) ) {
01250 fprintf( TFile, "%sAfter Vho Lowering\n%s",DBar,DBar );
01251 fdump_tree(TFile, wn_tree);
01252 }
01253
01254
01255
01256
01257
01258 LOWER_ACTIONS lower_flags = LOWER_NULL;
01259
01260 if (PU_has_namelist(Get_Current_PU()))
01261 lower_flags |= LOWER_IO_STATEMENT;
01262
01263 if (WOPT_Enable_Lower_Short_Circuit ||
01264 (Cur_PU_Feedback && !WOPT_Enable_Lower_Short_Circuit_Set))
01265 lower_flags |= LOWER_SHORTCIRCUIT;
01266
01267 if (! WOPT_Enable_Bits_Load_Store)
01268 lower_flags |= LOWER_BITS_OP;
01269
01270 if (lower_flags != LOWER_NULL) {
01271 wn_tree = WN_Lower(wn_tree, lower_flags, alias_mgr,
01272 "Pre_opt: special lowering for NAMELIST");
01273 if (Cur_PU_Feedback)
01274 Cur_PU_Feedback->Reset_Root_WN(wn_tree);
01275 }
01276
01277
01278 if (dont_opt) return wn_tree;
01279
01280 }
01281
01282 Opt_memory_init_pools();
01283
01284
01285 if (WOPT_Enable_Goto &&
01286 (phase == PREOPT_LNO_PHASE
01287 || phase == PREOPT_PHASE
01288 #ifdef TARG_NVISA
01289 || phase == PREOPT_CMC_PHASE
01290 #endif
01291 )) {
01292 #ifdef KEY
01293
01294 if ( Query_Skiplist ( Goto_Skip_List, Current_PU_Count() ) ) {
01295 if ( Show_Progress )
01296 ErrMsg(EC_Skip_PU, " goto conversion", Current_PU_Count(), Cur_PU_Name);
01297 }
01298 else {
01299 #endif
01300 SET_OPT_PHASE("Goto conversion");
01301 OPT_POOL_Push( &Opt_local_pool, MEM_DUMP_FLAG+2 );
01302 {
01303 GOTO_TABLE goto_table( wn_tree, &Opt_local_pool );
01304 goto_table.Remove_Gotos();
01305
01306 }
01307 OPT_POOL_Pop( &Opt_local_pool, MEM_DUMP_FLAG+2 );
01308
01309 if ( Get_Trace( TP_GLOBOPT, OPT_LOWER_FLAG ) ) {
01310 fprintf( TFile, "%sAfter Goto Conversion\n%s",DBar,DBar );
01311 fdump_tree(TFile, wn_tree);
01312 }
01313 #ifdef KEY
01314 }
01315 #endif
01316 }
01317
01318 SET_OPT_PHASE("Preparation");
01319
01320 #ifdef SKIP
01321
01322 Is_True(sizeof(CODEREP) == 48,
01323 ("Size of CODEREP has been changed (is now %d)!",sizeof(CODEREP)));
01324 #if defined(linux) || defined(BUILD_OS_DARWIN)
01325 Is_True(sizeof(STMTREP) == 60,
01326 ("Size of STMTREP has been changed (is now %d)!",sizeof(STMTREP)));
01327 #else
01328 Is_True(sizeof(STMTREP) == 64,
01329 ("Size of STMTREP has been changed (is now %d)!",sizeof(STMTREP)));
01330 #endif
01331 #endif
01332
01333
01334 COMP_UNIT *comp_unit = CXX_NEW(COMP_UNIT(wn_tree, alias_mgr,
01335 (OPT_PHASE)phase, &Opt_global_pool, &Opt_local_pool),
01336 &Opt_global_pool);
01337
01338 #ifdef Is_True_On
01339 g_comp_unit = comp_unit;
01340
01341 #endif
01342
01343 Is_True(comp_unit->Cfg()->Verify_tree(comp_unit->Input_tree()),
01344 ("Verifying CFG wrong"));
01345
01346
01347 BOOL lower_fully = (phase == MAINOPT_PHASE);
01348
01349
01350 REGION_LEVEL rgn_level = (lower_fully) ? RL_MAINOPT :
01351 RID_preopt_level(phase);
01352
01353
01354
01355 SET_OPT_PHASE("Create AUX Symbol table");
01356 WN_Simplifier_Enable(TRUE);
01357 comp_unit->Opt_stab()->Create(comp_unit, rgn_level);
01358 if (WOPT_Enable_Pt_Summary) {
01359 comp_unit->Opt_stab()->Points_to_summarizer()->
01360 Bind_callee_points_to_summary (wn_tree);
01361 }
01362
01363 MEM_POOL alias_class_pool;
01364
01365 OPT_POOL_Initialize(&alias_class_pool, "Alias classification pool",
01366 FALSE, MEM_DUMP_FLAG+20);
01367
01368 ALIAS_CLASSIFICATION ac(comp_unit->Opt_stab(),
01369 AC_DESTINATION_OPT_STAB,
01370 &alias_class_pool);
01371
01372 comp_unit->Opt_stab()->Set_alias_classification(ac);
01373
01374
01375
01376
01377 if (WOPT_Enable_Alias_Classification &&
01378 !REGION_has_black_regions(comp_unit->Rid())) {
01379 SET_OPT_PHASE("Compute alias classification");
01380 ac.Classify_memops(comp_unit->Input_tree());
01381 comp_unit->Opt_stab()->Incorporate_alias_class_info();
01382 }
01383
01384 #ifdef Is_True_On
01385 g_opt_stab = comp_unit->Opt_stab();
01386 #endif
01387 WN_Simplifier_Enable(FALSE);
01388 WN_Simp_Fold_ILOAD = Fold_ILOAD_save;;
01389 WN_Simp_Fold_LDA = Fold_LDA_save;;
01390
01391
01392 SET_OPT_PHASE("Create CFG");
01393
01394
01395 BOOL do_tail_rec = ((! IS_FORTRAN) && WOPT_Enable_Tail_Recur);
01396
01397 comp_unit->Cfg()->Create(comp_unit->Input_tree(), lower_fully,
01398 WOPT_Enable_Calls_Break_BB,
01399 rgn_level,
01400 comp_unit->Opt_stab(), do_tail_rec );
01401
01402
01403
01404 if (Cur_PU_Feedback) {
01405 SET_OPT_PHASE("Annotate CFG with feedback from Whirl");
01406 OPT_FEEDBACK *feedback = CXX_NEW(OPT_FEEDBACK(comp_unit->Cfg(),
01407 &Opt_global_pool),
01408 &Opt_global_pool);
01409 comp_unit->Cfg()->Set_feedback( feedback );
01410 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01411 "after CFG Annotation" );
01412
01413 }
01414
01415 SET_OPT_PHASE("Control Flow Analysis");
01416 comp_unit->Cfg()->Compute_dom_tree(TRUE);
01417 comp_unit->Cfg()->Compute_dom_tree(FALSE);
01418 comp_unit->Cfg()->Remove_fake_entryexit_arcs();
01419 comp_unit->Cfg()->Compute_dom_frontier();
01420 comp_unit->Cfg()->Compute_control_dependence();
01421 comp_unit->Cfg()->Analyze_loops();
01422
01423
01424 SET_OPT_PHASE("Create MU and CHI list");
01425 comp_unit->Opt_stab()->Compute_FFA(comp_unit->Rid());
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436 Is_True(comp_unit->Cfg()->Verify_cfg(),
01437 ("Verify CFG wrong after MU and CHI"));
01438
01439 SET_OPT_PHASE("Create SSA Representation");
01440
01441 comp_unit->Ssa()->Construct(comp_unit->Htable(),
01442 comp_unit->Cfg(),
01443 comp_unit->Opt_stab());
01444
01445
01446
01447
01448
01449
01450
01451 comp_unit->Opt_stab()->Alias_classification()->Release_resources();
01452 if (WOPT_Enable_Pt_Summary) {
01453 SET_OPT_PHASE("Points-to Summary Annotation");
01454 comp_unit->Opt_stab()->Points_to_summarizer()->
01455 Annotate_points_to_summary();
01456 }
01457
01458 SET_OPT_PHASE("SSA Pointer Alias Analysis");
01459 comp_unit->Ssa()->Pointer_Alias_Analysis();
01460 SET_OPT_PHASE("Dead Store Elimination");
01461 comp_unit->Ssa()->Dead_store_elim(comp_unit->Cfg(),
01462 comp_unit->Opt_stab(),
01463 comp_unit->Exc());
01464
01465 comp_unit->Opt_stab()->Update_return_mu();
01466 Analyze_pu_attr (comp_unit->Opt_stab(), Opt_current_pu_st);
01467
01468 if (WOPT_Enable_Zero_Version) {
01469 SET_OPT_PHASE("Find Zero Versions");
01470 comp_unit->Ssa()->Find_zero_versions();
01471 }
01472
01473 SET_OPT_PHASE("Create CODEMAP Representation");
01474 comp_unit->Ssa()->Create_CODEMAP();
01475
01476 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01477 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01478 } else {
01479 SET_OPT_PHASE("Verify Live-Range");
01480 comp_unit->Verify_version();
01481 }
01482
01483 SET_OPT_PHASE("Verify DO-loop");
01484 Detect_invalid_doloops(comp_unit);
01485
01486 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(), comp_unit->Htable(), 1),
01487 ("Verify CFG wrong after Htable"));
01488
01489 #ifdef TARG_NVISA
01490
01491
01492 if (phase == MAINOPT_PHASE || phase == PREOPT_CMC_PHASE) {
01493 #endif
01494
01495
01496
01497
01498 Do_Pre_Before_Ivr(comp_unit);
01499
01500
01501 if (WOPT_Enable_IVR) {
01502 SET_OPT_PHASE("Induction Variable Recognition");
01503 comp_unit->Do_iv_recognition();
01504 }
01505
01506
01507 if (WOPT_Enable_Copy_Propagate) {
01508 SET_OPT_PHASE("Copy Propagation");
01509 comp_unit->Do_copy_propagate();
01510 }
01511
01512 if (WOPT_Enable_Bool_Simp) {
01513 SET_OPT_PHASE("Boolean simplification");
01514 Simplify_bool_expr(comp_unit);
01515 }
01516
01517 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(), comp_unit->Htable(), 2),
01518 ("Verify CFG wrong after copy prop"));
01519
01520
01521 if (WOPT_Enable_DCE) {
01522 SET_OPT_PHASE("Dead Code Elimination");
01523 BOOL dce_renumber_pregs = This_preopt_renumbers_pregs(phase);
01524 comp_unit->Do_dead_code_elim(TRUE, TRUE, TRUE, TRUE,
01525 WOPT_Enable_Copy_Propagate,
01526 dce_renumber_pregs,
01527 NULL);
01528
01529 if ( comp_unit->Cfg()->Feedback() )
01530 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01531 "after Dead Code Elimination" );
01532 }
01533
01534 #ifdef KEY
01535 if (WOPT_Enable_Warn_Uninit && phase == MAINOPT_PHASE)
01536 comp_unit->Find_uninitialized_locals();
01537 #endif
01538
01539 #ifdef KEY // moved here because renaming causes bad code when there is
01540
01541 if ( WOPT_Enable_Fold_Lda_Iload_Istore ) {
01542 SET_OPT_PHASE("LDA-ILOAD/ISTORE folding in coderep");
01543 comp_unit->Fold_lda_iload_istore();
01544 }
01545 #endif
01546
01547 for (INT i = 0; i < WOPT_Enable_Extra_Rename_Pass; ++i) {
01548
01549 if (Get_Trace(TP_WOPT2, SECOND_RENAME_FLAG))
01550 fprintf(TFile, "%sEXTRA RENAME PASS %d:\n%s", DBar, i+1, DBar);
01551
01552
01553
01554
01555 if (WOPT_Enable_CFG_Opt && phase == MAINOPT_PHASE) {
01556 SET_OPT_PHASE("CFG optimization");
01557 CFG_transformation(comp_unit,
01558 WOPT_Enable_CFG_Opt2 && i == 0,
01559 Get_Trace(TP_WOPT2, CFG_OPT_FLAG),
01560 WOPT_Enable_CFG_Display);
01561
01562 if ( comp_unit->Cfg()->Feedback() )
01563 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01564 "after CFG Optimization" );
01565 }
01566
01567 SET_OPT_PHASE("Second rename");
01568 Rename_CODEMAP(comp_unit);
01569
01570 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01571 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01572 } else {
01573 SET_OPT_PHASE("Verify Live-Range");
01574 comp_unit->Verify_version();
01575 }
01576
01577
01578 if (WOPT_Enable_Copy_Propagate) {
01579 SET_OPT_PHASE("Copy Propagation");
01580 comp_unit->Do_copy_propagate();
01581 }
01582
01583 if (WOPT_Enable_DCE) {
01584 SET_OPT_PHASE("Dead Code Elimination");
01585 BOOL paths_removed;
01586 BOOL dce_renumber_pregs = This_preopt_renumbers_pregs(phase);
01587 comp_unit->Do_dead_code_elim(TRUE, TRUE, TRUE, TRUE,
01588 WOPT_Enable_Copy_Propagate,
01589 dce_renumber_pregs,
01590 &paths_removed);
01591
01592 if ( comp_unit->Cfg()->Feedback() )
01593 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01594 "Dead Code Elimination" );
01595
01596 if (!paths_removed) break;
01597 }
01598
01599 #ifdef KEY // moved here because renaming causes bad code when there is
01600
01601 if ( WOPT_Enable_Fold_Lda_Iload_Istore ) {
01602 SET_OPT_PHASE("LDA-ILOAD/ISTORE folding in coderep");
01603 comp_unit->Fold_lda_iload_istore();
01604 }
01605 #endif
01606
01607
01608
01609
01610 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01611 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01612 } else {
01613 SET_OPT_PHASE("Verify Live-Range");
01614 comp_unit->Verify_version();
01615 }
01616 }
01617
01618 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(), comp_unit->Htable(), 3),
01619 ("Verify CFG wrong after extra passes"));
01620
01621 if (WOPT_Enable_Edge_Placement && phase == MAINOPT_PHASE) {
01622 SET_OPT_PHASE("Remove Critical Edge");
01623 Is_Trace( Get_Trace(TP_GLOBOPT, EPRE_DUMP_FLAG),
01624 ( TFile, "-------CFG before edge placement---------\n" ) );
01625 Is_Trace_cmd( Get_Trace(TP_GLOBOPT, EPRE_DUMP_FLAG),
01626 comp_unit->Cfg()->Print(TFile) );
01627 INT count = comp_unit->Cfg()->Remove_critical_edge();
01628 Is_Trace( Get_Trace(TP_GLOBOPT, EPRE_DUMP_FLAG),
01629 ( TFile, "After edge Placement: BBs are placed on %d edges\n",
01630 count ) );
01631 Is_Trace_cmd( (count>0 && Get_Trace(TP_GLOBOPT, EPRE_DUMP_FLAG)),
01632 comp_unit->Cfg()->Print(TFile) );
01633
01634 if ( comp_unit->Cfg()->Feedback() )
01635 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01636 "after Edge Placement" );
01637 }
01638
01639 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01640 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01641 } else {
01642 SET_OPT_PHASE("Verify Live-Range");
01643 comp_unit->Verify_version();
01644 }
01645
01646 #ifdef Is_True_On
01647 SET_OPT_PHASE("Verify CODEMAP");
01648 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(),comp_unit->Htable(),4),
01649 ("Verify CFG wrong after dce"));
01650 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01651 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01652 else {
01653 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01654 comp_unit->Htable()->Verify_hashing();
01655 }
01656 #endif // Is_True_On
01657
01658 if(WOPT_Enable_WOVP){
01659 WOVP wovp(comp_unit->Cfg(), comp_unit->Opt_stab());
01660 wovp.Do_wovp();
01661 }
01662
01663 #ifdef TARG_NVISA
01664 }
01665 #endif
01666
01667
01668 WN *opt_wn;
01669 if ( phase == MAINOPT_PHASE ) {
01670 #if defined(TARG_IA64) || defined(TARG_NVISA)
01671 if (WHIRL_Mtype_B_On)
01672 comp_unit->Introduce_mtype_bool();
01673 #endif
01674
01675 if (WOPT_Enable_Bits_Load_Store) {
01676 SET_OPT_PHASE("{I,}{LD,ST}BITS lowering in coderep");
01677 comp_unit->Lower_to_extract_compose();
01678
01679 }
01680
01681 if (WOPT_Enable_SSA_PRE) {
01682 if (WOPT_Enable_Exp_PRE) {
01683
01684 if ( phase == MAINOPT_PHASE ) {
01685 comp_unit->Do_vnfre(TRUE);
01686 }
01687
01688 SET_OPT_PHASE("SSA PRE");
01689 comp_unit->Do_new_pre();
01690
01691 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01692 fprintf(TFile, "%sAfter Do_new_pre\n%s", DBar, DBar);
01693 comp_unit->Htable()->Print(TFile);
01694 }
01695
01696 comp_unit->Do_vnfre(FALSE);
01697
01698 #ifdef Is_True_On
01699 SET_OPT_PHASE("Verify CODEMAP");
01700 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(),comp_unit->Htable(),5),
01701 ("Verify CFG wrong after dce"));
01702 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01703 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01704 else
01705 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01706 #endif // Is_True_On
01707 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01708 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01709 } else {
01710 SET_OPT_PHASE("Verify Live-Range");
01711 comp_unit->Verify_version();
01712 }
01713 }
01714
01715 if (WOPT_Enable_DCE) {
01716 SET_OPT_PHASE("Dead Code Elimination 2");
01717 comp_unit->Do_dead_code_elim(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
01718 NULL);
01719
01720 if ( comp_unit->Cfg()->Feedback() )
01721 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01722 "after Dead Code"
01723 " Elimination 2" );
01724 }
01725
01726 if (Only_Unsigned_64_Bit_Ops && Delay_U64_Lowering) {
01727 SET_OPT_PHASE("U64 lowering in coderep");
01728 comp_unit->U64_lower_cr(FALSE);
01729 }
01730
01731 if (WOPT_Enable_Local_Rvi) {
01732 SET_OPT_PHASE("Local RVI");
01733 comp_unit->Do_local_rvi();
01734
01735 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01736 fprintf(TFile,"%sAfter Do_local_rvi\n%s", DBar, DBar);
01737 comp_unit->Htable()->Print(TFile);
01738 comp_unit->Cfg()->Print(TFile);
01739 }
01740
01741 #ifdef Is_True_On
01742 SET_OPT_PHASE("Verify CODEMAP");
01743
01744 if (!Get_Trace(TKIND_INFO, TINFO_TIME))
01745 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01746 #endif // Is_True_On
01747
01748 if (!Get_Trace(TKIND_INFO, TINFO_TIME)) {
01749 SET_OPT_PHASE("Verify Live-Range");
01750 comp_unit->Verify_version();
01751 }
01752 }
01753 else comp_unit->Find_lr_shrink_cand();
01754
01755 if (WOPT_Enable_Load_PRE) {
01756 SET_OPT_PHASE("Load PRE");
01757 comp_unit->Htable()->Verify_var_phi_hash();
01758 comp_unit->Do_load_pre(WOPT_Enable_Const_PRE ,
01759 !WOPT_Enable_Lpre_Before_Ivr );
01760
01761 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01762 fprintf(TFile, "%sAfter Load PRE\n%s", DBar, DBar);
01763 comp_unit->Htable()->Print(TFile);
01764 }
01765
01766 #ifdef Is_True_On
01767 SET_OPT_PHASE("Verify CODEMAP");
01768
01769 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01770 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01771 else
01772 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01773 #endif // Is_True_On
01774 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01775 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01776 } else {
01777 SET_OPT_PHASE("Verify Live-Range");
01778 comp_unit->Verify_version();
01779 }
01780 }
01781
01782 if (WOPT_Enable_Store_PRE && !WOPT_Enable_Spre_Before_Ivr) {
01783 SET_OPT_PHASE("Store PRE");
01784 comp_unit->Htable()->Verify_var_phi_hash();
01785 comp_unit->Do_store_pre();
01786
01787 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01788 fprintf(TFile, "%sAfter Store PRE\n%s", DBar, DBar);
01789 comp_unit->Htable()->Print(TFile);
01790 }
01791
01792 #ifdef Is_True_On
01793 SET_OPT_PHASE("Verify CODEMAP");
01794
01795 if (Get_Trace(TKIND_INFO, TINFO_TIME))
01796 SET_OPT_PHASE("Skip verify CODEMAP because timing trace is on");
01797 else {
01798 Is_True(comp_unit->Verify_CODEMAP(), ("CODEMAP corrupted."));
01799 comp_unit->Htable()->Verify_hashing();
01800 }
01801 #endif // Is_True_On
01802 if (Get_Trace(TKIND_INFO, TINFO_TIME)) {
01803 SET_OPT_PHASE("Skip verify Live-Range because timing trace is on");
01804 } else {
01805 SET_OPT_PHASE("Verify Live-Range");
01806 comp_unit->Verify_version();
01807 }
01808 }
01809
01810 if (WOPT_Enable_Bitwise_DCE) {
01811 SET_OPT_PHASE("Bitwise DCE");
01812 comp_unit->Do_bitwise_dce(TRUE );
01813 }
01814
01815 #if defined(TARG_SL)
01816 SET_OPT_PHASE("LOCAL_CLSC");
01817 if (WOPT_Enable_Local_Clsc && (!WOPT_Enable_RVI1)) {
01818 LOCAL_CLSC lclsc(comp_unit->Cfg(), comp_unit->Opt_stab());
01819 lclsc.Do_local_clsc();
01820 if (Get_Trace(TP_GLOBOPT, CR_DUMP_FLAG)) {
01821 fprintf(TFile,"%sAfter lclsc\n%s", DBar, DBar);
01822 comp_unit->Htable()->Print(TFile);
01823 comp_unit->Cfg()->Print(TFile);
01824 }
01825 }
01826 #endif
01827
01828 if (WOPT_Enable_RVI) {
01829
01830
01831 SET_OPT_PHASE("RVI hooks for SSA PRE");
01832 comp_unit->
01833 Set_pre_rvi_hooks(CXX_NEW(PRE_RVI_HOOKS(comp_unit->Opt_stab(),
01834 comp_unit->Cfg(),
01835 &Opt_local_pool,
01836 Get_Trace(TP_GLOBOPT,
01837 EPRE_DUMP_FLAG)),
01838 &Opt_local_pool));
01839 #if 0
01840
01841 comp_unit->Opt_stab()->Screen_rvi_candidates();
01842 #endif
01843 }
01844
01845
01846 RVI rvi(WOPT_Enable_RVI, comp_unit->Opt_stab(),
01847 WOPT_Enable_RVI ? comp_unit->Pre_rvi_hooks()->Nbits() : 0,
01848 alias_mgr );
01849
01850 Is_True(comp_unit->Verify_IR(comp_unit->Cfg(),comp_unit->Htable(),6),
01851 ("Verify CFG wrong after creating RVI instance"));
01852
01853 if (Get_Trace(TP_GLOBOPT, ENABLE_STAT)) {
01854 comp_unit->Collect_statistics();
01855 }
01856
01857 SET_OPT_PHASE("MainOpt emitter");
01858
01859 if ( comp_unit->Cfg()->Feedback() )
01860 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01861 "before MainOpt emitter" );
01862 if (comp_unit->Cfg()->Feedback() &&
01863 comp_unit->Cfg()->Feedback()->Trace())
01864 comp_unit->Cfg()->Feedback()->Print( TFile );
01865
01866 opt_wn = comp_unit->Emit_ML_WHIRL(&rvi);
01867 if (Cur_PU_Feedback)
01868 Cur_PU_Feedback->Reset_Root_WN(opt_wn);
01869
01870 Is_True(REGION_consistency_check(opt_wn),(""));
01871 Is_True(Verify_alias(alias_mgr,opt_wn),(""));
01872
01873 #if !defined(TARG_IA32) && !defined(TARG_X8664)
01874 if ( WOPT_Enable_RVI ) {
01875 SET_OPT_PHASE("RVI");
01876 opt_wn = rvi.Perform_RVI( opt_wn, alias_mgr );
01877 if (Cur_PU_Feedback)
01878 Cur_PU_Feedback->Reset_Root_WN(opt_wn);
01879 Is_True(REGION_consistency_check(opt_wn),(""));
01880 Is_True(Verify_alias(alias_mgr,opt_wn),(""));
01881 }
01882 #endif
01883
01884
01885
01886 CXX_DELETE(comp_unit, &Opt_global_pool);
01887 Opt_memory_terminate_pools();
01888
01889 }
01890
01891 }
01892 else {
01893 if (WOPT_Enable_Loop_Multiver) {
01894 LOOP_MULTIVER lm (comp_unit);
01895 lm.Perform_loop_multiversioning ();
01896 }
01897
01898 SET_OPT_PHASE("Emitter");
01899
01900 if ( comp_unit->Cfg()->Feedback() )
01901 comp_unit->Cfg()->Feedback()->Verify( comp_unit->Cfg(),
01902 "before emitter" );
01903
01904 if (This_preopt_renumbers_pregs(phase)) {
01905 comp_unit->Emitter()->Preg_renumbering_map().Init();
01906 }
01907 opt_wn = comp_unit->Emitter()->Emit(comp_unit, du_mgr, alias_mgr);
01908 if (Cur_PU_Feedback)
01909 Cur_PU_Feedback->Reset_Root_WN(opt_wn);
01910
01911
01912
01913
01914
01915
01916
01917 if (Run_ipl) {
01918 Set_Error_Phase ( "IPA Summary" );
01919 WB_IPL_Save();
01920 WB_IPL_Initialize(opt_wn, du_mgr, alias_mgr);
01921 Perform_Procedure_Summary_Phase (opt_wn, du_mgr, alias_mgr,
01922 comp_unit->Emitter());
01923 WB_IPL_Terminate();
01924 WB_IPL_Restore();
01925 }
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938 if (phase == PREOPT_LNO_PHASE &&
01939 This_preopt_renumbers_pregs(phase) &&
01940 WOPT_Enable_Second_Alias_Class &&
01941 !REGION_has_black_regions(comp_unit->Rid())) {
01942 SET_OPT_PHASE("Repeat alias classification for LNO");
01943 alias_mgr->Forget_alias_class_info();
01944 OPT_POOL_Initialize(&alias_class_pool, "Alias classification pool",
01945 FALSE, MEM_DUMP_FLAG+20);
01946 ALIAS_CLASSIFICATION ac(comp_unit->Opt_stab(),
01947 AC_DESTINATION_ALIAS_MANAGER,
01948 &alias_class_pool);
01949 ac.Classify_memops(opt_wn);
01950
01951
01952
01953 alias_mgr->Transfer_alias_class_to_alias_manager(ac, opt_wn);
01954 ac.Release_resources();
01955 }
01956
01957 if (This_preopt_renumbers_pregs(phase)) {
01958 Set_PU_Info_flags(Current_PU_Info, PU_PREGS_RENUMBERED);
01959 }
01960
01961 CXX_DELETE(comp_unit, &Opt_global_pool);
01962 Opt_memory_terminate_pools();
01963
01964 if (WN_opcode(opt_wn) == OPC_FUNC_ENTRY)
01965 Verify_SYMTAB (CURRENT_SYMTAB);
01966 }
01967
01968
01969 RID *rid = REGION_get_rid(opt_wn);
01970 Is_True(rid != NULL, ("Pre_Optimizer, NULL RID after processing"));
01971 RID_level(rid) = RID_preopt_level(phase);
01972
01973 SET_OPT_PHASE("Finalize");
01974
01975 REPORT_STATISTICS();
01976
01977 if (phase == MAINOPT_PHASE &&
01978 Current_Dep_Graph != NULL && Get_Trace(TP_LNOPT, 1)) {
01979
01980 fprintf(TFile, "%sLNO dep graph for CG, after WOPT\n%s", DBar, DBar);
01981 Current_Dep_Graph->Print(TFile);
01982 fprintf(TFile, "%s", DBar);
01983 }
01984
01985 Is_True(REGION_consistency_check(opt_wn),(""));
01986
01987 if (Get_Trace( TP_GLOBOPT, ALIAS_DUMP_FLAG)){
01988 Dump_alias_mgr(alias_mgr, opt_wn, TFile);
01989 }
01990
01991 disable_tree_freq_display();
01992
01993 WN_verifier(opt_wn);
01994
01995 if (WN_opcode(opt_wn) == OPC_FUNC_ENTRY)
01996 Set_PU_Info_tree_ptr (Current_PU_Info, opt_wn);
01997
01998 WN_CopyMap(opt_wn, WN_MAP_FEEDBACK, wn_orig);
01999
02000 return opt_wn;
02001 }