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 #ifdef USE_PCH
00060 #include "opt_pch.h"
00061 #endif // USE_PCH
00062 #pragma hdrstop
00063
00064
00065 #ifdef _KEEP_RCS_ID
00066 #define opt_htable_emit_CXX "opt_htable_emit.cxx"
00067 static char *rcs_id = opt_htable_emit_CXX"$Revision: 1.5 $";
00068 #endif
00069
00070 #include "limits.h"
00071 #include "defs.h"
00072 #include "tracing.h"
00073 #include "config_targ.h"
00074 #include "wn.h"
00075 #include "wn_simp.h"
00076 #include "wn_util.h"
00077
00078 #include "opt_alias_mgr.h"
00079 #include "opt_base.h"
00080 #include "opt_bb.h"
00081 #include "opt_cfg.h"
00082 #include "opt_htable.h"
00083 #include "opt_main.h"
00084 #include "opt_mu_chi.h"
00085 #include "opt_region_emit.h"
00086 #include "opt_rvi.h"
00087 #include "opt_sym.h"
00088
00089 #include "opt_emit_template.h"
00090
00091 class RVI;
00092
00093 class ML_WHIRL_EMITTER {
00094 private:
00095 CFG *_cfg;
00096 CODEMAP *_htable;
00097 OPT_STAB *_opt_stab;
00098 WN *_opt_func;
00099 STMT_CONTAINER _wn_list;
00100 MEM_POOL *_loc_pool;
00101 MEM_POOL *_mem_pool;
00102 ALIAS_MANAGER *_alias_mgr;
00103 BOOL _do_rvi;
00104 RVI *_rvi;
00105 BOOL _trace;
00106
00107 STACK<E_REGION*> _region_stack;
00108
00109 ID_MAP<IDTYPE, INT32> _preg_renumbering_map;
00110
00111
00112
00113 ML_WHIRL_EMITTER(const ML_WHIRL_EMITTER&);
00114 ML_WHIRL_EMITTER& operator = (const ML_WHIRL_EMITTER&);
00115
00116 WN *Emit(void);
00117
00118 void Gen_stmt(STMTREP*);
00119
00120 void Create_entry(BB_NODE *bb);
00121 STACK<E_REGION *> *Region_stack(void) { return &_region_stack; }
00122
00123 void Pop_region(void);
00124
00125 public:
00126 ML_WHIRL_EMITTER(CFG *cfg,
00127 OPT_STAB *opt_stab,
00128 CODEMAP *htable,
00129 ALIAS_MANAGER *alias_mgr,
00130 RVI *rvi,
00131 MEM_POOL *lpool,
00132 MEM_POOL *gpool);
00133 ~ML_WHIRL_EMITTER(void) {}
00134
00135 OPT_STAB *Opt_stab(void) const { return _opt_stab; }
00136 MEM_POOL *Loc_pool(void) const { return _loc_pool; }
00137 MEM_POOL *Mem_pool(void) const { return _mem_pool; }
00138 CFG *Cfg(void) const { return _cfg; }
00139 CODEMAP *Htable(void) const { return _htable; }
00140 WN *Opt_func(void) const { return _opt_func; }
00141 STMT_CONTAINER *Wn_list(void) { return &_wn_list; }
00142 ALIAS_MANAGER *Alias_Mgr(void) const { return _alias_mgr; }
00143 BOOL Trace(void) const { return _trace; }
00144 BOOL For_preopt(void) const { return FALSE; }
00145
00146 void Gen_wn(BB_NODE *f,
00147 BB_NODE *l);
00148 void Insert_wn(WN *wn) { _wn_list.Append(wn); }
00149
00150 BOOL Verify(WN *wn);
00151 WN *Build_loop_info(BB_NODE *);
00152
00153
00154 ID_MAP<IDTYPE, INT32> &Preg_renumbering_map(void)
00155 { return _preg_renumbering_map; }
00156
00157 BOOL Gen_lno_info(void) { return TRUE; }
00158 BOOL Do_rvi(void) const
00159 { return WOPT_Enable_RVI1 && _do_rvi; }
00160 RVI *Rvi(void) const { return _rvi; };
00161
00162 void Connect_sr_wn(STMTREP*,
00163 WN *) {}
00164 void Set_region_entry_stmt(STMTREP*) {}
00165 STMTREP *Region_entry_stmt(void) { return NULL; }
00166
00167 WN_MAP *Wn_to_cr_map(void) { return NULL; }
00168 };
00169
00170
00171
00172 void
00173 ML_WHIRL_EMITTER::Create_entry(BB_NODE *bb)
00174 {
00175
00176 WN *stmt = WN_CreateBlock();
00177 WN_first(stmt) = Wn_list()->Head();
00178 WN_last(stmt) = Wn_list()->Tail();
00179
00180 WN *wn = bb->Entrywn();
00181 Is_True(wn != NULL,("ML_WHIRL_EMITTER::Create_entry, wn is NULL"));
00182
00183 WN_Set_Linenum(stmt, WN_Get_Linenum(wn));
00184 _opt_func = wn;
00185 bb->Init_stmt(_opt_func);
00186
00187 WN_func_body(_opt_func) = stmt;
00188 REGION_emit(Cfg()->Rid(), _opt_func, RL_MAINOPT, 1, 0);
00189 }
00190
00191 void
00192 ML_WHIRL_EMITTER::Gen_stmt(STMTREP *stmt)
00193 {
00194 WN *wn = Gen_stmt_wn(stmt, Wn_list(), this);
00195
00196
00197 }
00198
00199 BOOL
00200 ML_WHIRL_EMITTER::Verify(WN *wn)
00201 {
00202 return TRUE;
00203 }
00204
00205 void
00206 ML_WHIRL_EMITTER::Pop_region( void )
00207 {
00208 E_REGION *e_region = _region_stack.Pop();
00209 WN *prev_wn = e_region->Prev_wn();
00210 WN *last_region_wn = _wn_list.Tail();
00211 WN *first_region_wn = prev_wn ? WN_next(prev_wn) : _wn_list.Head();
00212 BB_REGION *bb_region = e_region->Region_start()->Regioninfo();
00213
00214
00215
00216 if (!first_region_wn) {
00217 Is_True(prev_wn == _wn_list.Tail(),
00218 ("ML_WHIRL_EMITTER::Pop_region, prev_wn mistake"));
00219 last_region_wn = NULL;
00220 }
00221
00222
00223 WN *region_body = WN_CreateBlock();
00224 WN_first(region_body) = first_region_wn;
00225 WN_last(region_body) = last_region_wn;
00226
00227 WN *region_wn = WN_CreateRegion(REGION_type_to_kind(bb_region->Rid()),
00228 region_body,
00229 bb_region->Region_pragma_list(),
00230 bb_region->Region_exit_list(),
00231 RID_id(bb_region->Rid()),
00232 bb_region->Ereg_supp());
00233
00234
00235 if (REGION_is_EH(region_wn))
00236 Opt_stab()->Convert_EH_pragmas(region_wn);
00237
00238
00239
00240 if ( first_region_wn != NULL )
00241 WN_prev(first_region_wn) = NULL;
00242 Is_True( last_region_wn == NULL || WN_next(last_region_wn) == NULL,
00243 ("MAIN_EMITTER::Pop_region: last_region_wn has non-null next") );
00244
00245 if ( prev_wn != NULL )
00246 WN_next(prev_wn) = region_wn;
00247 WN_prev(region_wn) = prev_wn;
00248 _wn_list.Set_tail(region_wn);
00249
00250 if ( first_region_wn == _wn_list.Head() )
00251 _wn_list.Set_head(region_wn);
00252
00253
00254 REGION_emit(bb_region->Rid(), region_wn, RL_MAINOPT,
00255 bb_region->Region_num_exits(), bb_region->Region_line_num());
00256 }
00257
00258
00259
00260
00261
00262
00263 WN *
00264 ML_WHIRL_EMITTER::Build_loop_info( BB_NODE *label_bb )
00265 {
00266 if ( label_bb->Label_loop_info() == NULL )
00267 return NULL;
00268
00269 UINT16 est_trips = WN_loop_trip_est(label_bb->Label_loop_info());
00270 UINT16 depth = WN_loop_depth(label_bb->Label_loop_info());
00271 INT32 lflags = WN_loop_flag(label_bb->Label_loop_info());
00272
00273
00274
00275 BB_NODE *dohead_bb = label_bb->Prev();
00276 if ( dohead_bb == NULL || dohead_bb->Kind() != BB_DOHEAD ) {
00277
00278 return NULL;
00279 }
00280
00281
00282
00283 BB_LOOP *bb_loop = dohead_bb->Loop();
00284 if ( bb_loop == NULL || bb_loop->Body() != label_bb ) {
00285 return NULL;
00286 }
00287
00288 BB_NODE *doend_bb = bb_loop->End();
00289 if ( doend_bb == NULL ||
00290 (doend_bb->Kind() != BB_DOEND &&
00291 doend_bb->Kind() != BB_WHILEEND && doend_bb->Kind() != BB_REPEATEND) ) {
00292
00293 return NULL;
00294 }
00295
00296
00297 if ( ! dohead_bb->Dominates_strictly( doend_bb ) ) {
00298 return NULL;
00299 }
00300
00301
00302 if ( Cfg()->Feedback() ) {
00303 FB_FREQ
00304 freq_trips = Cfg()->Feedback()->Get_node_freq_out( doend_bb->Id() );
00305 freq_trips /= Cfg()->Feedback()->Get_node_freq_out( dohead_bb->Id() );
00306 if ( freq_trips.Known() ) {
00307 INT32 trips = INT32( freq_trips.Value() + 0.5 );
00308
00309 est_trips = (trips <= USHRT_MAX) ? trips : USHRT_MAX;
00310 }
00311 }
00312
00313
00314 if (bb_loop->Child() == NULL)
00315 lflags |= WN_LOOP_INNERMOST;
00316 else
00317 lflags &= ~WN_LOOP_INNERMOST;
00318
00319
00320
00321 WN *trip_count = NULL;
00322 WN *induction = NULL;
00323
00324
00325 if ( bb_loop->Iv_replacement() != NULL ) {
00326 induction = Gen_exp_wn(bb_loop->Iv_replacement(), this);
00327 }
00328 else {
00329 CODEREP *iv = bb_loop->Iv();
00330 if (iv != NULL && iv->Kind() == CK_VAR &&
00331 (Do_rvi() && iv->Bitpos() != ILLEGAL_BP ||
00332 !Do_rvi()))
00333 {
00334 MTYPE ivtype = TY_mtype(iv->Lod_ty());
00335 #ifdef KEY // bug 5645
00336 if (ivtype == MTYPE_M)
00337 ivtype = iv->Dtyp();
00338 #endif
00339
00340 induction = WN_CreateLdid(Ldid_from_mtype(ivtype),
00341 iv->Offset(),
00342 Opt_stab()->St(iv->Aux_id()),
00343 iv->Lod_ty(),
00344 iv->Field_id());
00345 if (Do_rvi() && ST_class(WN_st(induction)) != CLASS_PREG) {
00346 Warn_todo("ML_WHIRL_EMITTER::Build_loop_info: do not adjust bitpos by 1" );
00347 Rvi()->Map_bitpos(induction, iv->Bitpos() + 1);
00348 }
00349 Alias_Mgr()->Gen_alias_id(induction, iv->Points_to(Opt_stab()));
00350 }
00351 }
00352
00353
00354 if ( induction == NULL ) {
00355 return NULL;
00356 }
00357
00358 if (bb_loop->Trip_count_stmt() != NULL) {
00359 if (bb_loop->Wn_trip_count() != NULL)
00360 trip_count = bb_loop->Wn_trip_count();
00361 } else {
00362 if (bb_loop->Trip_count_expr())
00363 trip_count = Gen_exp_wn(bb_loop->Trip_count_expr(), this);
00364 }
00365
00366 WN *loop_info = WN_CreateLoopInfo( induction, trip_count,
00367 est_trips, depth, lflags );
00368 return loop_info;
00369 }
00370
00371
00372
00373
00374 WN *
00375 ML_WHIRL_EMITTER::Emit(void)
00376 {
00377 if (Trace())
00378 fprintf(TFile,"%sML_WHIRL_EMITTER\n%s",DBar,DBar);
00379
00380
00381 Is_True(Cfg()->Rid() != NULL, ("ML_WHIRL_EMITTER::Emit, NULL RID"));
00382 if (!RID_TYPE_func_entry(Cfg()->Rid())) {
00383
00384 PRUNE_BOUND prune(Cfg(), Opt_stab());
00385
00386 }
00387
00388
00389
00390 Cfg()->Analyze_loops();
00391
00392 BOOL saved_wn_simp_enable = WN_Simplifier_Enable(FALSE);
00393
00394
00395 Cfg()->Delete_empty_BB();
00396
00397
00398 BB_NODE *bb;
00399 CFG_ITER cfg_iter;
00400 FOR_ALL_ELEM(bb, cfg_iter, Init(Cfg())) {
00401 if (bb->Reached()) {
00402
00403 if (Trace())
00404 fprintf(TFile,"----- BB%d -----\n",bb->Id());
00405
00406
00407 if ( bb->Kind() == BB_REGIONSTART ) {
00408 WN *prev_wn = _wn_list.Tail();
00409 Push_region(Region_stack(), bb, Loc_pool());
00410 E_REGION *e_region = _region_stack.Top();
00411 e_region->Set_prev_wn(prev_wn);
00412 Is_Trace(Trace(),(TFile,"Push_region(RGN %d), prev_wn = 0x%p\n",
00413 RID_id(bb->Regioninfo()->Rid()),prev_wn));
00414 }
00415
00416
00417 if ( bb->Kind() == BB_ENTRY && bb->Entrywn() &&
00418 (WN_opcode(bb->Entrywn()) == OPC_ALTENTRY ||
00419 (WN_opcode(bb->Entrywn()) == OPC_LABEL &&
00420 (WN_Label_Is_Handler_Begin(bb->Entrywn())
00421 #ifdef KEY
00422 || LABEL_target_of_goto_outer_block(WN_label_number(bb->Entrywn()))
00423 #endif
00424 ))) )
00425 {
00426 Insert_wn( bb->Entrywn() );
00427
00428 }
00429
00430
00431 BOOL generate_comments = Get_Trace(TP_GLOBOPT, 0xffffffff);
00432 WN *comment_wn = NULL;
00433 if ( generate_comments ) {
00434 char str[120];
00435 sprintf(str,"BB%03d (%s) %40.40s", bb->Id(), bb->Kind_name(), SBar);
00436 comment_wn = WN_CreateComment(str);
00437 WN_Set_Linenum(comment_wn, bb->Linenum());
00438
00439
00440
00441 if ( bb->Label_stmtrep() == NULL ) {
00442 Insert_wn( comment_wn );
00443 comment_wn = NULL;
00444 }
00445 }
00446
00447 STMTREP_ITER stmt_iter(bb->Stmtlist());
00448 STMTREP *tmp;
00449 FOR_ALL_NODE(tmp, stmt_iter, Init()) {
00450 if ( tmp->Live_stmt() )
00451 Gen_stmt(tmp);
00452
00453 OPERATOR stmt_opr = OPCODE_operator(tmp->Op());
00454
00455
00456 if ( stmt_opr == OPR_LABEL && comment_wn != NULL ) {
00457 Insert_wn( comment_wn );
00458 comment_wn = NULL;
00459 }
00460 }
00461
00462 bb->Set_wngend();
00463
00464
00465 while (_region_stack.Elements() > 0 &&
00466 _region_stack.Top()->Region_end() == bb) {
00467 Is_Trace(Trace(),(TFile,"Pop_region(RGN %d), prev_wn = 0x%p\n",
00468 RID_id(_region_stack.Top()->Region_start()->Regioninfo()->Rid()),
00469 _region_stack.Top()->Prev_wn()));
00470 Pop_region();
00471 }
00472 }
00473 }
00474
00475
00476 Is_True( _region_stack.Elements() == 0,
00477 ("ML_WHIRL_EMITTER::Emit: region stack not empty") );
00478
00479
00480 BB_NODE *entry_bb = Cfg()->Find_entry_bb();
00481 if (entry_bb->Kind() == BB_ENTRY) {
00482
00483 Create_entry(entry_bb);
00484 } else {
00485 Is_True(entry_bb->Kind() == BB_REGIONSTART,
00486 ("ML_WHIRL_EMITTER::Emit, unknown entry kind %s",
00487 entry_bb->Kind_name()));
00488 _opt_func = _wn_list.Head();
00489 Is_True(REGION_consistency_check(_opt_func),
00490 ("ML_WHIRL_EMITTER::Emit, inconsistent region"));
00491 }
00492
00493
00494 Is_True(Get_Preg_Num(PREG_Table_Size(CURRENT_SYMTAB)) ==
00495 Opt_stab()->Last_preg(),
00496 ("ML_WHIRL_EMITTER::Emit, incorrect last preg number"));
00497
00498
00499
00500
00501 if (Trace()) {
00502 fprintf(TFile,"%sAfter ML_WHIRL_EMITTER\n%s",DBar,DBar);
00503 _alias_mgr->Print(_opt_func, TFile);
00504 Print_dep_graph(TFile);
00505 }
00506
00507
00508
00509 REGION_update_alias_info(_opt_func,_alias_mgr);
00510
00511 if (Opt_stab()->Phase() == MAINOPT_PHASE) {
00512 BOOL tr = Trace() || Get_Trace (TP_GLOBOPT, ALIAS_DUMP_FLAG);
00513 Opt_stab()->Cr_sr_annot_mgr()->
00514 Export_annot (_opt_func, _alias_mgr, TRUE, tr);
00515 WN_MEMOP_ANNOT_MGR::WN_mem_annot_mgr()->Set_active_mgr();
00516 }
00517
00518 Verify(_opt_func);
00519
00520 Is_True(REGION_consistency_check(_opt_func),(""));
00521
00522 WN_Simplifier_Enable(saved_wn_simp_enable);
00523
00524 return _opt_func;
00525 }
00526
00527 ML_WHIRL_EMITTER::ML_WHIRL_EMITTER(CFG *cfg,
00528 OPT_STAB *opt_stab,
00529 CODEMAP *htable,
00530 ALIAS_MANAGER *alias_mgr,
00531 RVI *rvi,
00532 MEM_POOL *lpool,
00533 MEM_POOL *gpool)
00534 :_cfg(cfg), _opt_stab(opt_stab), _htable(htable), _alias_mgr(alias_mgr),
00535 _rvi(rvi), _do_rvi(rvi->Do_rvi()), _mem_pool(gpool), _loc_pool(lpool),
00536 _region_stack(lpool), _preg_renumbering_map(128, 0, lpool, FALSE)
00537 {
00538 _trace = Get_Trace(TP_GLOBOPT, MAIN_EMIT_DUMP_FLAG);
00539 Emit();
00540 }
00541
00542 WN*
00543 COMP_UNIT::Emit_ML_WHIRL(RVI *rvi)
00544 {
00545
00546
00547 ML_WHIRL_EMITTER emitter(Cfg(),
00548 Opt_stab(),
00549 Htable(),
00550 Alias_mgr(),
00551 rvi,
00552 Loc_pool(),
00553 Mem_pool());
00554 return emitter.Opt_func();
00555 }